/* this is a file autogenerated by spice_codegen.py */
/*
  Copyright (C) 2013 Red Hat, Inc.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <common/messages.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <spice/protocol.h>
#include <spice/macros.h>
#include <common/mem.h>

#ifdef _MSC_VER
#pragma warning(disable:4101)
#endif



#ifdef WORDS_BIGENDIAN
#define read_int8(ptr) (*((int8_t *)(ptr)))
#define write_int8(ptr, val) *(int8_t *)(ptr) = val
#define read_uint8(ptr) (*((uint8_t *)(ptr)))
#define write_uint8(ptr, val) *(uint8_t *)(ptr) = val
#define read_int16(ptr) ((int16_t)SPICE_BYTESWAP16(*((uint16_t *)(ptr))))
#define write_int16(ptr, val) *(uint16_t *)(ptr) = SPICE_BYTESWAP16((uint16_t)val)
#define read_uint16(ptr) ((uint16_t)SPICE_BYTESWAP16(*((uint16_t *)(ptr))))
#define write_uint16(ptr, val) *(uint16_t *)(ptr) = SPICE_BYTESWAP16((uint16_t)val)
#define read_int32(ptr) ((int32_t)SPICE_BYTESWAP32(*((uint32_t *)(ptr))))
#define write_int32(ptr, val) *(uint32_t *)(ptr) = SPICE_BYTESWAP32((uint32_t)val)
#define read_uint32(ptr) ((uint32_t)SPICE_BYTESWAP32(*((uint32_t *)(ptr))))
#define write_uint32(ptr, val) *(uint32_t *)(ptr) = SPICE_BYTESWAP32((uint32_t)val)
#define read_int64(ptr) ((int64_t)SPICE_BYTESWAP64(*((uint64_t *)(ptr))))
#define write_int64(ptr, val) *(uint64_t *)(ptr) = SPICE_BYTESWAP64((uint64_t)val)
#define read_uint64(ptr) ((uint64_t)SPICE_BYTESWAP64(*((uint64_t *)(ptr))))
#define write_uint64(ptr, val) *(uint64_t *)(ptr) = SPICE_BYTESWAP64((uint64_t)val)
#else
#define read_int8(ptr) (*((int8_t *)(ptr)))
#define write_int8(ptr, val) (*((int8_t *)(ptr))) = val
#define read_uint8(ptr) (*((uint8_t *)(ptr)))
#define write_uint8(ptr, val) (*((uint8_t *)(ptr))) = val
#define read_int16(ptr) (*((int16_t *)(ptr)))
#define write_int16(ptr, val) (*((int16_t *)(ptr))) = val
#define read_uint16(ptr) (*((uint16_t *)(ptr)))
#define write_uint16(ptr, val) (*((uint16_t *)(ptr))) = val
#define read_int32(ptr) (*((int32_t *)(ptr)))
#define write_int32(ptr, val) (*((int32_t *)(ptr))) = val
#define read_uint32(ptr) (*((uint32_t *)(ptr)))
#define write_uint32(ptr, val) (*((uint32_t *)(ptr))) = val
#define read_int64(ptr) (*((int64_t *)(ptr)))
#define write_int64(ptr, val) (*((int64_t *)(ptr))) = val
#define read_uint64(ptr) (*((uint64_t *)(ptr)))
#define write_uint64(ptr, val) (*((uint64_t *)(ptr))) = val
#endif

static int8_t SPICE_GNUC_UNUSED consume_int8(uint8_t **ptr)
{
    int8_t val;
    val = read_int8(*ptr);
    *ptr += 1;
    return val;
}

static uint8_t SPICE_GNUC_UNUSED consume_uint8(uint8_t **ptr)
{
    uint8_t val;
    val = read_uint8(*ptr);
    *ptr += 1;
    return val;
}

static int16_t SPICE_GNUC_UNUSED consume_int16(uint8_t **ptr)
{
    int16_t val;
    val = read_int16(*ptr);
    *ptr += 2;
    return val;
}

static uint16_t SPICE_GNUC_UNUSED consume_uint16(uint8_t **ptr)
{
    uint16_t val;
    val = read_uint16(*ptr);
    *ptr += 2;
    return val;
}

static int32_t SPICE_GNUC_UNUSED consume_int32(uint8_t **ptr)
{
    int32_t val;
    val = read_int32(*ptr);
    *ptr += 4;
    return val;
}

static uint32_t SPICE_GNUC_UNUSED consume_uint32(uint8_t **ptr)
{
    uint32_t val;
    val = read_uint32(*ptr);
    *ptr += 4;
    return val;
}

static int64_t SPICE_GNUC_UNUSED consume_int64(uint8_t **ptr)
{
    int64_t val;
    val = read_int64(*ptr);
    *ptr += 8;
    return val;
}

static uint64_t SPICE_GNUC_UNUSED consume_uint64(uint8_t **ptr)
{
    uint64_t val;
    val = read_uint64(*ptr);
    *ptr += 8;
    return val;
}
static int SPICE_GNUC_UNUSED consume_fd(uint8_t **ptr)
{
    return -1;
}

typedef struct PointerInfo PointerInfo;
typedef void (*message_destructor_t)(uint8_t *message);
typedef uint8_t * (*parse_func_t)(uint8_t *message_start, uint8_t *message_end, uint8_t *struct_data, PointerInfo *ptr_info, int minor);
typedef uint8_t * (*parse_msg_func_t)(uint8_t *message_start, uint8_t *message_end, int minor, size_t *size_out, message_destructor_t *free_message);
typedef uint8_t * (*spice_parse_channel_func_t)(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, int minor, size_t *size_out, message_destructor_t *free_message);

struct PointerInfo {
    uint64_t offset;
    parse_func_t parse;
    void * *dest;
    uint32_t nelements;
};

static uint8_t * parse_msg_migrate(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgMigrate *out;

    nw_size = 4;
    mem_size = sizeof(SpiceMsgMigrate);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgMigrate);
    in = start;

    out = (SpiceMsgMigrate *)data;

    out->flags = consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static void nofree(SPICE_GNUC_UNUSED uint8_t *data)
{
}

static uint8_t * parse_SpiceMsgData(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t data__nw_size;
    uint32_t data__nelements;

    { /* data */
        data__nelements = message_end - (start + 0);

        data__nw_size = data__nelements;
    }

    nw_size = 0 + data__nw_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = message_start;
    *size = message_end - message_start;
    *free_message = nofree;
    return data;

}

static uint8_t * parse_msg_set_ack(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgSetAck *out;

    nw_size = 8;
    mem_size = sizeof(SpiceMsgSetAck);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgSetAck);
    in = start;

    out = (SpiceMsgSetAck *)data;

    out->generation = consume_uint32(&in);
    out->window = consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_ping(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    size_t data__nw_size;
    uint32_t data__nelements;
    SpiceMsgPing *out;

    { /* data */
        data__nelements = message_end - (start + 12);

        data__nw_size = data__nelements;
    }

    nw_size = 12 + data__nw_size;
    mem_size = sizeof(SpiceMsgPing);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgPing);
    in = start;

    out = (SpiceMsgPing *)data;

    out->id = consume_uint32(&in);
    out->timestamp = consume_uint64(&in);
    /* use array as pointer */
    out->data = (uint8_t *)in;
    out->data_len = data__nelements;
    in += data__nelements;

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_wait_for_channels(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    size_t wait_list__nw_size, wait_list__mem_size;
    uint32_t wait_list__nelements;
    SpiceMsgWaitForChannels *out;
    uint32_t i;

    { /* wait_list */
        uint8_t wait_count__value;
        pos = start + 0;
        if (SPICE_UNLIKELY(pos + 1 > message_end)) {
            goto error;
        }
        wait_count__value = read_uint8(pos);
        wait_list__nelements = wait_count__value;

        wait_list__nw_size = (10) * wait_list__nelements;
        wait_list__mem_size = sizeof(SpiceWaitForChannel) * wait_list__nelements;
    }

    nw_size = 1 + wait_list__nw_size;
    mem_size = sizeof(SpiceMsgWaitForChannels) + wait_list__mem_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgWaitForChannels);
    in = start;

    out = (SpiceMsgWaitForChannels *)data;

    out->wait_count = consume_uint8(&in);
    for (i = 0; i < wait_list__nelements; i++) {
        SpiceWaitForChannel *out2;
        out2 = (SpiceWaitForChannel *)end;
        end += sizeof(SpiceWaitForChannel);

        out2->channel_type = consume_uint8(&in);
        out2->channel_id = consume_uint8(&in);
        out2->message_serial = consume_uint64(&in);
    }

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_disconnecting(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgDisconnect *out;

    nw_size = 12;
    mem_size = sizeof(SpiceMsgDisconnect);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisconnect);
    in = start;

    out = (SpiceMsgDisconnect *)data;

    out->time_stamp = consume_uint64(&in);
    out->reason = consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_notify(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    size_t message__nw_size, message__mem_size;
    uint32_t message__nelements;
    size_t zero__mem_size;
    SpiceMsgNotify *out;

    { /* message */
        uint32_t message_len__value;
        pos = start + 20;
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        message_len__value = read_uint32(pos);
        message__nelements = message_len__value;

        message__nw_size = message__nelements;
        message__mem_size = sizeof(uint8_t) * message__nelements;
    }

    { /* zero */
        zero__mem_size = sizeof(uint8_t);
    }

    nw_size = 25 + message__nw_size;
    mem_size = sizeof(SpiceMsgNotify) + message__mem_size + zero__mem_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgNotify);
    in = start;

    out = (SpiceMsgNotify *)data;

    out->time_stamp = consume_uint64(&in);
    out->severity = consume_uint32(&in);
    out->visibilty = consume_uint32(&in);
    out->what = consume_uint32(&in);
    out->message_len = consume_uint32(&in);
    memcpy(out->message, in, message__nelements);
    in += message__nelements;
    end += message__nelements;
    *(uint8_t *)end = consume_uint8(&in);
    end += sizeof(uint8_t);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_main_migrate_begin(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    size_t dst_info__nw_size;
    SpiceMsgMainMigrationBegin *out;

    { /* dst_info */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
        size_t dst_info_host_data__nw_size;
        uint32_t dst_info_host_data__nelements;
        size_t dst_info_pub_key_data__nw_size;
        uint32_t dst_info_pub_key_data__nelements;
        { /* host_data */
            uint32_t host_size__value;
            pos = start2 + 8;
            if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                goto error;
            }
            host_size__value = read_uint32(pos);
            dst_info_host_data__nelements = host_size__value;

            dst_info_host_data__nw_size = dst_info_host_data__nelements;
        }

        if (minor >= 1) { /* pub_key_data */
            uint32_t pub_key_size__value;
            pos = start2 + 12 + ((minor >= 1)?6:0);
            if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                goto error;
            }
            pub_key_size__value = read_uint32(pos);
            dst_info_pub_key_data__nelements = pub_key_size__value;

            dst_info_pub_key_data__nw_size = dst_info_pub_key_data__nelements;
        } else { /* minor < 1 */
            dst_info_pub_key_data__nelements = 0;
            dst_info_pub_key_data__nw_size = 0;
        }

        dst_info__nw_size = 12 + ((minor >= 1)?10:0) + dst_info_host_data__nw_size + dst_info_pub_key_data__nw_size;
    }

    nw_size = 0 + dst_info__nw_size;
    mem_size = sizeof(SpiceMsgMainMigrationBegin);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgMainMigrationBegin);
    in = start;

    out = (SpiceMsgMainMigrationBegin *)data;

    /* dst_info */ {
        uint32_t host_data__nelements;
        uint32_t pub_key_data__nelements;
        out->dst_info.port = consume_uint16(&in);
        out->dst_info.sport = consume_uint16(&in);
        consume_uint32(&in);
        out->dst_info.host_size = consume_uint32(&in);
        if (minor >= 1) {
            out->dst_info.pub_key_type = consume_uint16(&in);
        } else {
            out->dst_info.pub_key_type = 0;
        }
        if (minor >= 1) {
            consume_uint32(&in);
        } else {
        }
        if (minor >= 1) {
            out->dst_info.pub_key_size = consume_uint32(&in);
        } else {
            out->dst_info.pub_key_size = 0;
        }
        host_data__nelements = out->dst_info.host_size;
        /* use array as pointer */
        out->dst_info.host_data = (uint8_t *)in;
        in += host_data__nelements;
        if (minor >= 1) {
            pub_key_data__nelements = out->dst_info.pub_key_size;
            /* use array as pointer */
            out->dst_info.pub_key_data = (uint8_t *)in;
            in += pub_key_data__nelements;
        }
    }

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_SpiceMsgEmpty(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;

    nw_size = 0;
    mem_size = sizeof(SpiceMsgEmpty);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgEmpty);
    in = start;


    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_main_init(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgMainInit *out;

    nw_size = 32;
    mem_size = sizeof(SpiceMsgMainInit);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgMainInit);
    in = start;

    out = (SpiceMsgMainInit *)data;

    out->session_id = consume_uint32(&in);
    out->display_channels_hint = consume_uint32(&in);
    out->supported_mouse_modes = consume_uint32(&in);
    out->current_mouse_mode = consume_uint32(&in);
    out->agent_connected = consume_uint32(&in);
    out->agent_tokens = consume_uint32(&in);
    out->multi_media_time = consume_uint32(&in);
    out->ram_hint = consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_main_channels_list(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    size_t channels__nw_size, channels__mem_size;
    uint32_t channels__nelements;
    SpiceMsgChannels *out;
    uint32_t i;

    { /* channels */
        uint32_t num_of_channels__value;
        pos = start + 0;
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        num_of_channels__value = read_uint32(pos);
        channels__nelements = num_of_channels__value;

        channels__nw_size = (2) * channels__nelements;
        channels__mem_size = sizeof(SpiceChannelId) * channels__nelements;
    }

    nw_size = 4 + channels__nw_size;
    mem_size = sizeof(SpiceMsgChannels) + channels__mem_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgChannels);
    in = start;

    out = (SpiceMsgChannels *)data;

    out->num_of_channels = consume_uint32(&in);
    for (i = 0; i < channels__nelements; i++) {
        SpiceChannelId *out2;
        out2 = (SpiceChannelId *)end;
        end += sizeof(SpiceChannelId);

        out2->type = consume_uint8(&in);
        out2->id = consume_uint8(&in);
    }

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_main_mouse_mode(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgMainMouseMode *out;

    nw_size = 8;
    mem_size = sizeof(SpiceMsgMainMouseMode);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgMainMouseMode);
    in = start;

    out = (SpiceMsgMainMouseMode *)data;

    out->supported_modes = consume_uint32(&in);
    out->current_mode = consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_main_multi_media_time(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgMainMultiMediaTime *out;

    nw_size = 4;
    mem_size = sizeof(SpiceMsgMainMultiMediaTime);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgMainMultiMediaTime);
    in = start;

    out = (SpiceMsgMainMultiMediaTime *)data;

    out->time = consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_main_agent_disconnected(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgMainAgentDisconnect *out;

    nw_size = 4;
    mem_size = sizeof(SpiceMsgMainAgentDisconnect);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgMainAgentDisconnect);
    in = start;

    out = (SpiceMsgMainAgentDisconnect *)data;

    out->error_code = consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_main_agent_token(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgMainAgentTokens *out;

    nw_size = 4;
    mem_size = sizeof(SpiceMsgMainAgentTokens);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgMainAgentTokens);
    in = start;

    out = (SpiceMsgMainAgentTokens *)data;

    out->num_tokens = consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_main_migrate_switch_host(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    size_t host_data__nw_size;
    uint32_t host_data__nelements;
    size_t cert_subject_data__nw_size;
    uint32_t cert_subject_data__nelements;
    SpiceMsgMainMigrationSwitchHost *out;

    { /* host_data */
        uint32_t host_size__value;
        pos = start + 8;
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        host_size__value = read_uint32(pos);
        host_data__nelements = host_size__value;

        host_data__nw_size = host_data__nelements;
    }

    { /* cert_subject_data */
        uint32_t cert_subject_size__value;
        pos = start + 16;
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        cert_subject_size__value = read_uint32(pos);
        cert_subject_data__nelements = cert_subject_size__value;

        cert_subject_data__nw_size = cert_subject_data__nelements;
    }

    nw_size = 20 + host_data__nw_size + cert_subject_data__nw_size;
    mem_size = sizeof(SpiceMsgMainMigrationSwitchHost);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgMainMigrationSwitchHost);
    in = start;

    out = (SpiceMsgMainMigrationSwitchHost *)data;

    out->port = consume_uint16(&in);
    out->sport = consume_uint16(&in);
    consume_uint32(&in);
    out->host_size = consume_uint32(&in);
    consume_uint32(&in);
    out->cert_subject_size = consume_uint32(&in);
    /* use array as pointer */
    out->host_data = (uint8_t *)in;
    in += host_data__nelements;
    /* use array as pointer */
    out->cert_subject_data = (uint8_t *)in;
    in += cert_subject_data__nelements;

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_MainChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
{
    static parse_msg_func_t funcs1[7] =  {
        parse_msg_migrate,
        parse_SpiceMsgData,
        parse_msg_set_ack,
        parse_msg_ping,
        parse_msg_wait_for_channels,
        parse_msg_disconnecting,
        parse_msg_notify
    };
    static parse_msg_func_t funcs2[11] =  {
        parse_msg_main_migrate_begin,
        parse_SpiceMsgEmpty,
        parse_msg_main_init,
        parse_msg_main_channels_list,
        parse_msg_main_mouse_mode,
        parse_msg_main_multi_media_time,
        parse_SpiceMsgEmpty,
        parse_msg_main_agent_disconnected,
        parse_SpiceMsgData,
        parse_msg_main_agent_token,
        parse_msg_main_migrate_switch_host
    };
    if (message_type >= 1 && message_type < 8) {
        return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
    } else if (message_type >= 101 && message_type < 112) {
        return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
    }
    return NULL;
}



static uint8_t * parse_msg_display_mode(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgDisplayMode *out;

    nw_size = 12;
    mem_size = sizeof(SpiceMsgDisplayMode);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayMode);
    in = start;

    out = (SpiceMsgDisplayMode *)data;

    out->x_res = consume_uint32(&in);
    out->y_res = consume_uint32(&in);
    out->bits = consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static intptr_t validate_SpiceClipRects(uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor)
{
    uint8_t *start = message_start + offset;
    SPICE_GNUC_UNUSED uint8_t *pos;
    size_t mem_size, nw_size;
    size_t rects__nw_size, rects__mem_size;
    uint32_t rects__nelements;

    if (offset == 0) {
        return 0;
    }

    if (SPICE_UNLIKELY(start >= message_end)) {
        goto error;
    }

    { /* rects */
        uint32_t num_rects__value;
        pos = start + 0;
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        num_rects__value = read_uint32(pos);
        rects__nelements = num_rects__value;

        rects__nw_size = (16) * rects__nelements;
        rects__mem_size = sizeof(SpiceRect) * rects__nelements;
    }

    nw_size = 4 + rects__nw_size;
    mem_size = sizeof(SpiceClipRects) + rects__mem_size;

    /* Check if struct fits in reported side */
    if (SPICE_UNLIKELY(start + nw_size > message_end)) {
        goto error;
    }
    return mem_size;

   error:
    return -1;
}

static uint8_t * parse_struct_SpiceClipRects(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
{
    uint8_t *in = message_start + this_ptr_info->offset;
    uint8_t *end;
    SpiceClipRects *out;
    uint32_t rects__nelements;
    uint32_t i;

    end = struct_data + sizeof(SpiceClipRects);
    out = (SpiceClipRects *)struct_data;

    out->num_rects = consume_uint32(&in);
    rects__nelements = out->num_rects;
    for (i = 0; i < rects__nelements; i++) {
        SpiceRect *out2;
        out2 = (SpiceRect *)end;
        end += sizeof(SpiceRect);

        out2->top = consume_int32(&in);
        out2->left = consume_int32(&in);
        out2->bottom = consume_int32(&in);
        out2->right = consume_int32(&in);
    }
    return end;
}

static uint8_t * parse_msg_display_copy_bits(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[1];
    size_t base__extra_size;
    SpiceMsgDisplayCopyBits *out;
    uint32_t i;

    { /* base */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
        size_t base_clip__extra_size;
        { /* clip */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
            size_t base_clip_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_CLIP_TYPE_RECTS) {
                    uint64_t base_clip_u_rects__value;
                    pos = (start3 + 4);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    base_clip_u_rects__value = read_uint64(pos);
                    ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
                } else if (1) {
                    base_clip_u__extra_size = 0;
                } else {
                    base_clip_u__extra_size = 0;
                }

            }

            base_clip__extra_size = base_clip_u__extra_size;
        }

        base__extra_size = base_clip__extra_size;
    }

    nw_size = 36;
    mem_size = sizeof(SpiceMsgDisplayCopyBits) + base__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayCopyBits);
    in = start;

    out = (SpiceMsgDisplayCopyBits *)data;

    /* base */ {
        out->base.surface_id = 0;
        /* box */ {
            out->base.box.top = consume_int32(&in);
            out->base.box.left = consume_int32(&in);
            out->base.box.bottom = consume_int32(&in);
            out->base.box.right = consume_int32(&in);
        }
        /* clip */ {
            out->base.clip.type = consume_uint32(&in);
            if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
                ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
                n_ptr++;
            } else if (1) {
                consume_uint64(&in);
            }
        }
    }
    /* src_pos */ {
        out->src_pos.x = consume_int32(&in);
        out->src_pos.y = consume_int32(&in);
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_inval_list(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    size_t resources__nw_size, resources__mem_size;
    uint32_t resources__nelements;
    SpiceResourceList *out;
    uint32_t i;

    { /* resources */
        uint16_t count__value;
        pos = start + 0;
        if (SPICE_UNLIKELY(pos + 2 > message_end)) {
            goto error;
        }
        count__value = read_uint16(pos);
        resources__nelements = count__value;

        resources__nw_size = (9) * resources__nelements;
        resources__mem_size = sizeof(SpiceResourceID) * resources__nelements;
    }

    nw_size = 2 + resources__nw_size;
    mem_size = sizeof(SpiceResourceList) + resources__mem_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceResourceList);
    in = start;

    out = (SpiceResourceList *)data;

    out->count = consume_uint16(&in);
    for (i = 0; i < resources__nelements; i++) {
        SpiceResourceID *out2;
        out2 = (SpiceResourceID *)end;
        end += sizeof(SpiceResourceID);

        out2->type = consume_uint8(&in);
        out2->id = consume_uint64(&in);
    }

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_inval_all_pixmaps(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    size_t wait_list__nw_size, wait_list__mem_size;
    uint32_t wait_list__nelements;
    SpiceMsgWaitForChannels *out;
    uint32_t i;

    { /* wait_list */
        uint8_t wait_count__value;
        pos = start + 0;
        if (SPICE_UNLIKELY(pos + 1 > message_end)) {
            goto error;
        }
        wait_count__value = read_uint8(pos);
        wait_list__nelements = wait_count__value;

        wait_list__nw_size = (10) * wait_list__nelements;
        wait_list__mem_size = sizeof(SpiceWaitForChannel) * wait_list__nelements;
    }

    nw_size = 1 + wait_list__nw_size;
    mem_size = sizeof(SpiceMsgWaitForChannels) + wait_list__mem_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgWaitForChannels);
    in = start;

    out = (SpiceMsgWaitForChannels *)data;

    out->wait_count = consume_uint8(&in);
    for (i = 0; i < wait_list__nelements; i++) {
        SpiceWaitForChannel *out2;
        out2 = (SpiceWaitForChannel *)end;
        end += sizeof(SpiceWaitForChannel);

        out2->channel_type = consume_uint8(&in);
        out2->channel_id = consume_uint8(&in);
        out2->message_serial = consume_uint64(&in);
    }

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_inval_palette(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgDisplayInvalOne *out;

    nw_size = 8;
    mem_size = sizeof(SpiceMsgDisplayInvalOne);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayInvalOne);
    in = start;

    out = (SpiceMsgDisplayInvalOne *)data;

    out->id = consume_uint64(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_stream_create(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[1];
    size_t clip__extra_size;
    SpiceMsgDisplayStreamCreate *out;
    uint32_t i;

    { /* clip */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 52);
        size_t clip_u__extra_size;
        uint32_t type__value;
        { /* u */
            pos = start2 + 0;
            if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                goto error;
            }
            type__value = read_uint32(pos);
            if (type__value == SPICE_CLIP_TYPE_RECTS) {
                uint64_t clip_u_rects__value;
                pos = (start2 + 4);
                if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                    goto error;
                }
                clip_u_rects__value = read_uint64(pos);
                ptr_size = validate_SpiceClipRects(message_start, message_end, clip_u_rects__value, minor);
                if (SPICE_UNLIKELY(ptr_size < 0)) {
                    goto error;
                }
                clip_u__extra_size = ptr_size + /* for alignment */ 3;
            } else if (1) {
                clip_u__extra_size = 0;
            } else {
                clip_u__extra_size = 0;
            }

        }

        clip__extra_size = clip_u__extra_size;
    }

    nw_size = 64;
    mem_size = sizeof(SpiceMsgDisplayStreamCreate) + clip__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayStreamCreate);
    in = start;

    out = (SpiceMsgDisplayStreamCreate *)data;

    out->surface_id = 0;
    out->id = consume_uint32(&in);
    out->flags = consume_uint32(&in);
    out->codec_type = consume_uint32(&in);
    out->stamp = consume_uint64(&in);
    out->stream_width = consume_uint32(&in);
    out->stream_height = consume_uint32(&in);
    out->src_width = consume_uint32(&in);
    out->src_height = consume_uint32(&in);
    /* dest */ {
        out->dest.top = consume_int32(&in);
        out->dest.left = consume_int32(&in);
        out->dest.bottom = consume_int32(&in);
        out->dest.right = consume_int32(&in);
    }
    /* clip */ {
        out->clip.type = consume_uint32(&in);
        if (out->clip.type == SPICE_CLIP_TYPE_RECTS) {
            ptr_info[n_ptr].offset = consume_uint64(&in);
            ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
            ptr_info[n_ptr].dest = (void **)&out->clip.rects;
            n_ptr++;
        } else if (1) {
            consume_uint64(&in);
        }
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_stream_data(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    size_t data__nw_size, data__mem_size;
    uint32_t data__nelements;
    SpiceMsgDisplayStreamData *out;

    { /* data */
        uint32_t data_size__value;
        pos = start + 8;
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        data_size__value = read_uint32(pos);
        data__nelements = data_size__value;

        data__nw_size = data__nelements;
        data__mem_size = sizeof(uint8_t) * data__nelements;
    }

    nw_size = 16 + data__nw_size;
    mem_size = sizeof(SpiceMsgDisplayStreamData) + data__mem_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayStreamData);
    in = start;

    out = (SpiceMsgDisplayStreamData *)data;

    /* base */ {
        out->base.id = consume_uint32(&in);
        out->base.multi_media_time = consume_uint32(&in);
    }
    out->data_size = consume_uint32(&in);
    consume_uint32(&in);
    memcpy(out->data, in, data__nelements);
    in += data__nelements;
    end += data__nelements;

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_stream_clip(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[1];
    size_t clip__extra_size;
    SpiceMsgDisplayStreamClip *out;
    uint32_t i;

    { /* clip */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 4);
        size_t clip_u__extra_size;
        uint32_t type__value;
        { /* u */
            pos = start2 + 0;
            if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                goto error;
            }
            type__value = read_uint32(pos);
            if (type__value == SPICE_CLIP_TYPE_RECTS) {
                uint64_t clip_u_rects__value;
                pos = (start2 + 4);
                if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                    goto error;
                }
                clip_u_rects__value = read_uint64(pos);
                ptr_size = validate_SpiceClipRects(message_start, message_end, clip_u_rects__value, minor);
                if (SPICE_UNLIKELY(ptr_size < 0)) {
                    goto error;
                }
                clip_u__extra_size = ptr_size + /* for alignment */ 3;
            } else if (1) {
                clip_u__extra_size = 0;
            } else {
                clip_u__extra_size = 0;
            }

        }

        clip__extra_size = clip_u__extra_size;
    }

    nw_size = 16;
    mem_size = sizeof(SpiceMsgDisplayStreamClip) + clip__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayStreamClip);
    in = start;

    out = (SpiceMsgDisplayStreamClip *)data;

    out->id = consume_uint32(&in);
    /* clip */ {
        out->clip.type = consume_uint32(&in);
        if (out->clip.type == SPICE_CLIP_TYPE_RECTS) {
            ptr_info[n_ptr].offset = consume_uint64(&in);
            ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
            ptr_info[n_ptr].dest = (void **)&out->clip.rects;
            n_ptr++;
        } else if (1) {
            consume_uint64(&in);
        }
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_stream_destroy(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgDisplayStreamDestroy *out;

    nw_size = 4;
    mem_size = sizeof(SpiceMsgDisplayStreamDestroy);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayStreamDestroy);
    in = start;

    out = (SpiceMsgDisplayStreamDestroy *)data;

    out->id = consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static intptr_t validate_SpicePalette(uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor)
{
    uint8_t *start = message_start + offset;
    SPICE_GNUC_UNUSED uint8_t *pos;
    size_t mem_size, nw_size;
    size_t ents__nw_size, ents__mem_size;
    uint32_t ents__nelements;

    if (offset == 0) {
        return 0;
    }

    if (SPICE_UNLIKELY(start >= message_end)) {
        goto error;
    }

    { /* ents */
        uint16_t num_ents__value;
        pos = start + 8;
        if (SPICE_UNLIKELY(pos + 2 > message_end)) {
            goto error;
        }
        num_ents__value = read_uint16(pos);
        ents__nelements = num_ents__value;

        ents__nw_size = (4) * ents__nelements;
        ents__mem_size = sizeof(uint32_t) * ents__nelements;
    }

    nw_size = 10 + ents__nw_size;
    mem_size = sizeof(SpicePalette) + ents__mem_size;

    /* Check if struct fits in reported side */
    if (SPICE_UNLIKELY(start + nw_size > message_end)) {
        goto error;
    }
    return mem_size;

   error:
    return -1;
}

static intptr_t validate_SpiceImage(uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor)
{
    uint8_t *start = message_start + offset;
    SPICE_GNUC_UNUSED uint8_t *pos;
    size_t mem_size, nw_size;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    size_t u__nw_size, u__extra_size;
    uint8_t descriptor_type__value;

    if (offset == 0) {
        return 0;
    }

    if (SPICE_UNLIKELY(start >= message_end)) {
        goto error;
    }

    { /* u */
        pos = start + 8;
        if (SPICE_UNLIKELY(pos + 1 > message_end)) {
            goto error;
        }
        descriptor_type__value = read_uint8(pos);
        if (descriptor_type__value == SPICE_IMAGE_TYPE_BITMAP) {
            SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
            size_t u_pal__extra_size;
            uint8_t flags__value;
            size_t u_data__extra_size;
            uint32_t u_data__array__nelements;
            { /* pal */
                pos = start2 + 1;
                if (SPICE_UNLIKELY(pos + 1 > message_end)) {
                    goto error;
                }
                flags__value = read_uint8(pos);
                if ((flags__value & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
                    u_pal__extra_size = 0;
                } else if (1) {
                    uint64_t u_pal_palette__value;
                    pos = (start2 + 14);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    u_pal_palette__value = read_uint64(pos);
                    ptr_size = validate_SpicePalette(message_start, message_end, u_pal_palette__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    u_pal__extra_size = ptr_size + /* for alignment */ 3;
                } else {
                    u_pal__extra_size = 0;
                }

            }

            { /* data */
                uint64_t data__value;
                uint32_t u_data__array__nw_size;
                uint32_t stride__value;
                uint32_t y__value;
                pos = (start2 + 22);
                if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                    goto error;
                }
                data__value = read_uint64(pos);
                if (SPICE_UNLIKELY(message_start + data__value >= message_end)) {
                    goto error;
                }
                pos = start2 + 10;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                stride__value = read_uint32(pos);
                pos = start2 + 6;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                y__value = read_uint32(pos);
                u_data__array__nelements = stride__value * y__value;

                u_data__array__nw_size = u_data__array__nelements;
                if (SPICE_UNLIKELY(message_start + data__value + u_data__array__nw_size > message_end)) {
                    goto error;
                }
                u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
            }

            u__nw_size = 30;
            u__extra_size = u_pal__extra_size + u_data__extra_size;
        } else if (descriptor_type__value == SPICE_IMAGE_TYPE_QUIC) {
            SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
            size_t u_data__nw_size, u_data__extra_size;
            uint32_t u_data__nelements;
            { /* data */
                uint32_t data_size__value;
                pos = start2 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                data_size__value = read_uint32(pos);
                u_data__nelements = data_size__value;

                u_data__nw_size = u_data__nelements;
                u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
            }

            u__nw_size = 4 + u_data__nw_size;
            u__extra_size = u_data__extra_size;
        } else if (descriptor_type__value == SPICE_IMAGE_TYPE_LZ_RGB || descriptor_type__value == SPICE_IMAGE_TYPE_GLZ_RGB) {
            SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
            size_t u_data__nw_size, u_data__extra_size;
            uint32_t u_data__nelements;
            { /* data */
                uint32_t data_size__value;
                pos = start2 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                data_size__value = read_uint32(pos);
                u_data__nelements = data_size__value;

                u_data__nw_size = u_data__nelements;
                u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
            }

            u__nw_size = 4 + u_data__nw_size;
            u__extra_size = u_data__extra_size;
        } else if (descriptor_type__value == SPICE_IMAGE_TYPE_LZ_PLT) {
            SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
            size_t u_pal__extra_size;
            uint8_t flags__value;
            size_t u_data__nw_size, u_data__extra_size;
            uint32_t u_data__nelements;
            { /* pal */
                pos = start2 + 0;
                if (SPICE_UNLIKELY(pos + 1 > message_end)) {
                    goto error;
                }
                flags__value = read_uint8(pos);
                if ((flags__value & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
                    u_pal__extra_size = 0;
                } else if (1) {
                    uint64_t u_pal_palette__value;
                    pos = (start2 + 5);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    u_pal_palette__value = read_uint64(pos);
                    if (SPICE_UNLIKELY(u_pal_palette__value == 0)) {
                        goto error;
                    }
                    ptr_size = validate_SpicePalette(message_start, message_end, u_pal_palette__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    u_pal__extra_size = ptr_size + /* for alignment */ 3;
                } else {
                    u_pal__extra_size = 0;
                }

            }

            { /* data */
                uint32_t data_size__value;
                pos = start2 + 1;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                data_size__value = read_uint32(pos);
                u_data__nelements = data_size__value;

                u_data__nw_size = u_data__nelements;
                u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
            }

            u__nw_size = 13 + u_data__nw_size;
            u__extra_size = u_pal__extra_size + u_data__extra_size;
        } else {
            u__nw_size = 0;
            u__extra_size = 0;
        }

    }

    nw_size = 18 + u__nw_size;
    mem_size = sizeof(SpiceImage) + u__extra_size;

    /* Check if struct fits in reported side */
    if (SPICE_UNLIKELY(start + nw_size > message_end)) {
        goto error;
    }
    return mem_size;

   error:
    return -1;
}

static uint8_t * parse_struct_SpicePalette(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
{
    uint8_t *in = message_start + this_ptr_info->offset;
    uint8_t *end;
    SpicePalette *out;
    uint32_t ents__nelements;
    uint32_t i;

    end = struct_data + sizeof(SpicePalette);
    out = (SpicePalette *)struct_data;

    out->unique = consume_uint64(&in);
    out->num_ents = consume_uint16(&in);
    ents__nelements = out->num_ents;
    for (i = 0; i < ents__nelements; i++) {
        out->ents[i] = consume_uint32(&in);
        end += sizeof(uint32_t);
    }
    return end;
}

static uint8_t * parse_struct_SpiceImage(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
{
    uint8_t *in = message_start + this_ptr_info->offset;
    uint8_t *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[2];
    SpiceImage *out;
    uint32_t i;

    end = struct_data + sizeof(SpiceImage);
    out = (SpiceImage *)struct_data;

    /* descriptor */ {
        out->descriptor.id = consume_uint64(&in);
        out->descriptor.type = consume_uint8(&in);
        out->descriptor.flags = consume_uint8(&in);
        out->descriptor.width = consume_uint32(&in);
        out->descriptor.height = consume_uint32(&in);
    }
    if (out->descriptor.type == SPICE_IMAGE_TYPE_BITMAP) {
        uint32_t data__array__nelements;
        SpiceChunks *chunks;
        out->u.bitmap.format = consume_uint8(&in);
        out->u.bitmap.flags = consume_uint8(&in);
        out->u.bitmap.x = consume_uint32(&in);
        out->u.bitmap.y = consume_uint32(&in);
        out->u.bitmap.stride = consume_uint32(&in);
        if ((out->u.bitmap.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
            out->u.bitmap.palette_id = consume_uint64(&in);
        } else if (1) {
            ptr_info[n_ptr].offset = consume_uint64(&in);
            ptr_info[n_ptr].parse = parse_struct_SpicePalette;
            ptr_info[n_ptr].dest = (void **)&out->u.bitmap.palette;
            n_ptr++;
        }
        data__array__nelements = out->u.bitmap.stride * out->u.bitmap.y;
        /* Reuse data from network message as chunk */
        chunks = (SpiceChunks *)end;
        end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
        out->u.bitmap.data = chunks;
        chunks->data_size = data__array__nelements;
        chunks->flags = 0;
        chunks->num_chunks = 1;
        chunks->chunk[0].len = data__array__nelements;
        chunks->chunk[0].data = message_start + consume_uint64(&in);
    } else if (out->descriptor.type == SPICE_IMAGE_TYPE_QUIC) {
        uint32_t data__nelements;
        SpiceChunks *chunks;
        out->u.quic.data_size = consume_uint32(&in);
        data__nelements = out->u.quic.data_size;
        /* use array as chunk */
        chunks = (SpiceChunks *)end;
        end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
        out->u.quic.data = chunks;
        chunks->data_size = data__nelements;
        chunks->flags = 0;
        chunks->num_chunks = 1;
        chunks->chunk[0].len = data__nelements;
        chunks->chunk[0].data = in;
        in += data__nelements;
    } else if (out->descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB || out->descriptor.type == SPICE_IMAGE_TYPE_GLZ_RGB) {
        uint32_t data__nelements;
        SpiceChunks *chunks;
        out->u.lz_rgb.data_size = consume_uint32(&in);
        data__nelements = out->u.lz_rgb.data_size;
        /* use array as chunk */
        chunks = (SpiceChunks *)end;
        end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
        out->u.lz_rgb.data = chunks;
        chunks->data_size = data__nelements;
        chunks->flags = 0;
        chunks->num_chunks = 1;
        chunks->chunk[0].len = data__nelements;
        chunks->chunk[0].data = in;
        in += data__nelements;
    } else if (out->descriptor.type == SPICE_IMAGE_TYPE_LZ_PLT) {
        uint32_t data__nelements;
        SpiceChunks *chunks;
        out->u.lz_plt.flags = consume_uint8(&in);
        out->u.lz_plt.data_size = consume_uint32(&in);
        if ((out->u.lz_plt.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
            out->u.lz_plt.palette_id = consume_uint64(&in);
        } else if (1) {
            ptr_info[n_ptr].offset = consume_uint64(&in);
            ptr_info[n_ptr].parse = parse_struct_SpicePalette;
            ptr_info[n_ptr].dest = (void **)&out->u.lz_plt.palette;
            n_ptr++;
        }
        data__nelements = out->u.lz_plt.data_size;
        /* use array as chunk */
        chunks = (SpiceChunks *)end;
        end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
        out->u.lz_plt.data = chunks;
        chunks->data_size = data__nelements;
        chunks->flags = 0;
        chunks->num_chunks = 1;
        chunks->chunk[0].len = data__nelements;
        chunks->chunk[0].data = in;
        in += data__nelements;
    }

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    return end;

   error:
    return NULL;
}

static uint8_t * parse_msg_display_draw_fill(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[3];
    size_t base__extra_size;
    size_t data__extra_size;
    SpiceMsgDisplayDrawFill *out;
    uint32_t i;

    { /* base */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
        size_t base_clip__extra_size;
        { /* clip */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
            size_t base_clip_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_CLIP_TYPE_RECTS) {
                    uint64_t base_clip_u_rects__value;
                    pos = (start3 + 4);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    base_clip_u_rects__value = read_uint64(pos);
                    ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
                } else if (1) {
                    base_clip_u__extra_size = 0;
                } else {
                    base_clip_u__extra_size = 0;
                }

            }

            base_clip__extra_size = base_clip_u__extra_size;
        }

        base__extra_size = base_clip__extra_size;
    }

    { /* data */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
        size_t data_brush__extra_size;
        size_t data_mask__extra_size;
        { /* brush */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
            size_t data_brush_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_BRUSH_TYPE_SOLID) {
                    data_brush_u__extra_size = 0;
                } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
                    SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 4);
                    size_t data_brush_u_pat__extra_size;
                    { /* pat */
                        uint64_t pat__value;
                        pos = (start4 + 0);
                        if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                            goto error;
                        }
                        pat__value = read_uint64(pos);
                        if (SPICE_UNLIKELY(pat__value == 0)) {
                            goto error;
                        }
                        ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
                        if (SPICE_UNLIKELY(ptr_size < 0)) {
                            goto error;
                        }
                        data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
                    }

                    data_brush_u__extra_size = data_brush_u_pat__extra_size;
                } else {
                    data_brush_u__extra_size = 0;
                }

            }

            data_brush__extra_size = data_brush_u__extra_size;
        }

        { /* mask */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 22);
            size_t data_mask_bitmap__extra_size;
            { /* bitmap */
                uint64_t bitmap__value;
                pos = (start3 + 9);
                if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                    goto error;
                }
                bitmap__value = read_uint64(pos);
                ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
                if (SPICE_UNLIKELY(ptr_size < 0)) {
                    goto error;
                }
                data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
            }

            data_mask__extra_size = data_mask_bitmap__extra_size;
        }

        data__extra_size = data_brush__extra_size + data_mask__extra_size;
    }

    nw_size = 67;
    mem_size = sizeof(SpiceMsgDisplayDrawFill) + base__extra_size + data__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayDrawFill);
    in = start;

    out = (SpiceMsgDisplayDrawFill *)data;

    /* base */ {
        out->base.surface_id = 0;
        /* box */ {
            out->base.box.top = consume_int32(&in);
            out->base.box.left = consume_int32(&in);
            out->base.box.bottom = consume_int32(&in);
            out->base.box.right = consume_int32(&in);
        }
        /* clip */ {
            out->base.clip.type = consume_uint32(&in);
            if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
                ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
                n_ptr++;
            } else if (1) {
                consume_uint64(&in);
            }
        }
    }
    /* data */ {
        /* brush */ {
            uint8_t *in_save;
            out->data.brush.type = consume_uint32(&in);
            in_save = in;
            if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
                out->data.brush.u.color = consume_uint32(&in);
            } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceImage;
                ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
                n_ptr++;
                /* pos */ {
                    out->data.brush.u.pattern.pos.x = consume_int32(&in);
                    out->data.brush.u.pattern.pos.y = consume_int32(&in);
                }
            }
            in = in_save + 16;
        }
        out->data.rop_descriptor = consume_uint16(&in);
        /* mask */ {
            out->data.mask.flags = consume_uint8(&in);
            /* pos */ {
                out->data.mask.pos.x = consume_int32(&in);
                out->data.mask.pos.y = consume_int32(&in);
            }
            ptr_info[n_ptr].offset = consume_uint64(&in);
            ptr_info[n_ptr].parse = parse_struct_SpiceImage;
            ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
            n_ptr++;
        }
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_draw_opaque(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[4];
    size_t base__extra_size;
    size_t data__extra_size;
    SpiceMsgDisplayDrawOpaque *out;
    uint32_t i;

    { /* base */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
        size_t base_clip__extra_size;
        { /* clip */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
            size_t base_clip_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_CLIP_TYPE_RECTS) {
                    uint64_t base_clip_u_rects__value;
                    pos = (start3 + 4);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    base_clip_u_rects__value = read_uint64(pos);
                    ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
                } else if (1) {
                    base_clip_u__extra_size = 0;
                } else {
                    base_clip_u__extra_size = 0;
                }

            }

            base_clip__extra_size = base_clip_u__extra_size;
        }

        base__extra_size = base_clip__extra_size;
    }

    { /* data */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
        size_t data_src_bitmap__extra_size;
        size_t data_brush__extra_size;
        size_t data_mask__extra_size;
        { /* src_bitmap */
            uint64_t src_bitmap__value;
            pos = (start2 + 0);
            if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                goto error;
            }
            src_bitmap__value = read_uint64(pos);
            ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
            if (SPICE_UNLIKELY(ptr_size < 0)) {
                goto error;
            }
            data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
        }

        { /* brush */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 24);
            size_t data_brush_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_BRUSH_TYPE_SOLID) {
                    data_brush_u__extra_size = 0;
                } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
                    SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 4);
                    size_t data_brush_u_pat__extra_size;
                    { /* pat */
                        uint64_t pat__value;
                        pos = (start4 + 0);
                        if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                            goto error;
                        }
                        pat__value = read_uint64(pos);
                        if (SPICE_UNLIKELY(pat__value == 0)) {
                            goto error;
                        }
                        ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
                        if (SPICE_UNLIKELY(ptr_size < 0)) {
                            goto error;
                        }
                        data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
                    }

                    data_brush_u__extra_size = data_brush_u_pat__extra_size;
                } else {
                    data_brush_u__extra_size = 0;
                }

            }

            data_brush__extra_size = data_brush_u__extra_size;
        }

        { /* mask */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 47);
            size_t data_mask_bitmap__extra_size;
            { /* bitmap */
                uint64_t bitmap__value;
                pos = (start3 + 9);
                if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                    goto error;
                }
                bitmap__value = read_uint64(pos);
                ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
                if (SPICE_UNLIKELY(ptr_size < 0)) {
                    goto error;
                }
                data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
            }

            data_mask__extra_size = data_mask_bitmap__extra_size;
        }

        data__extra_size = data_src_bitmap__extra_size + data_brush__extra_size + data_mask__extra_size;
    }

    nw_size = 92;
    mem_size = sizeof(SpiceMsgDisplayDrawOpaque) + base__extra_size + data__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayDrawOpaque);
    in = start;

    out = (SpiceMsgDisplayDrawOpaque *)data;

    /* base */ {
        out->base.surface_id = 0;
        /* box */ {
            out->base.box.top = consume_int32(&in);
            out->base.box.left = consume_int32(&in);
            out->base.box.bottom = consume_int32(&in);
            out->base.box.right = consume_int32(&in);
        }
        /* clip */ {
            out->base.clip.type = consume_uint32(&in);
            if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
                ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
                n_ptr++;
            } else if (1) {
                consume_uint64(&in);
            }
        }
    }
    /* data */ {
        ptr_info[n_ptr].offset = consume_uint64(&in);
        ptr_info[n_ptr].parse = parse_struct_SpiceImage;
        ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
        n_ptr++;
        /* src_area */ {
            out->data.src_area.top = consume_int32(&in);
            out->data.src_area.left = consume_int32(&in);
            out->data.src_area.bottom = consume_int32(&in);
            out->data.src_area.right = consume_int32(&in);
        }
        /* brush */ {
            uint8_t *in_save;
            out->data.brush.type = consume_uint32(&in);
            in_save = in;
            if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
                out->data.brush.u.color = consume_uint32(&in);
            } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceImage;
                ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
                n_ptr++;
                /* pos */ {
                    out->data.brush.u.pattern.pos.x = consume_int32(&in);
                    out->data.brush.u.pattern.pos.y = consume_int32(&in);
                }
            }
            in = in_save + 16;
        }
        out->data.rop_descriptor = consume_uint16(&in);
        out->data.scale_mode = consume_uint8(&in);
        /* mask */ {
            out->data.mask.flags = consume_uint8(&in);
            /* pos */ {
                out->data.mask.pos.x = consume_int32(&in);
                out->data.mask.pos.y = consume_int32(&in);
            }
            ptr_info[n_ptr].offset = consume_uint64(&in);
            ptr_info[n_ptr].parse = parse_struct_SpiceImage;
            ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
            n_ptr++;
        }
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_draw_copy(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[3];
    size_t base__extra_size;
    size_t data__extra_size;
    SpiceMsgDisplayDrawCopy *out;
    uint32_t i;

    { /* base */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
        size_t base_clip__extra_size;
        { /* clip */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
            size_t base_clip_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_CLIP_TYPE_RECTS) {
                    uint64_t base_clip_u_rects__value;
                    pos = (start3 + 4);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    base_clip_u_rects__value = read_uint64(pos);
                    ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
                } else if (1) {
                    base_clip_u__extra_size = 0;
                } else {
                    base_clip_u__extra_size = 0;
                }

            }

            base_clip__extra_size = base_clip_u__extra_size;
        }

        base__extra_size = base_clip__extra_size;
    }

    { /* data */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
        size_t data_src_bitmap__extra_size;
        size_t data_mask__extra_size;
        { /* src_bitmap */
            uint64_t src_bitmap__value;
            pos = (start2 + 0);
            if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                goto error;
            }
            src_bitmap__value = read_uint64(pos);
            ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
            if (SPICE_UNLIKELY(ptr_size < 0)) {
                goto error;
            }
            data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
        }

        { /* mask */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 27);
            size_t data_mask_bitmap__extra_size;
            { /* bitmap */
                uint64_t bitmap__value;
                pos = (start3 + 9);
                if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                    goto error;
                }
                bitmap__value = read_uint64(pos);
                ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
                if (SPICE_UNLIKELY(ptr_size < 0)) {
                    goto error;
                }
                data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
            }

            data_mask__extra_size = data_mask_bitmap__extra_size;
        }

        data__extra_size = data_src_bitmap__extra_size + data_mask__extra_size;
    }

    nw_size = 72;
    mem_size = sizeof(SpiceMsgDisplayDrawCopy) + base__extra_size + data__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayDrawCopy);
    in = start;

    out = (SpiceMsgDisplayDrawCopy *)data;

    /* base */ {
        out->base.surface_id = 0;
        /* box */ {
            out->base.box.top = consume_int32(&in);
            out->base.box.left = consume_int32(&in);
            out->base.box.bottom = consume_int32(&in);
            out->base.box.right = consume_int32(&in);
        }
        /* clip */ {
            out->base.clip.type = consume_uint32(&in);
            if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
                ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
                n_ptr++;
            } else if (1) {
                consume_uint64(&in);
            }
        }
    }
    /* data */ {
        ptr_info[n_ptr].offset = consume_uint64(&in);
        ptr_info[n_ptr].parse = parse_struct_SpiceImage;
        ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
        n_ptr++;
        /* src_area */ {
            out->data.src_area.top = consume_int32(&in);
            out->data.src_area.left = consume_int32(&in);
            out->data.src_area.bottom = consume_int32(&in);
            out->data.src_area.right = consume_int32(&in);
        }
        out->data.rop_descriptor = consume_uint16(&in);
        out->data.scale_mode = consume_uint8(&in);
        /* mask */ {
            out->data.mask.flags = consume_uint8(&in);
            /* pos */ {
                out->data.mask.pos.x = consume_int32(&in);
                out->data.mask.pos.y = consume_int32(&in);
            }
            ptr_info[n_ptr].offset = consume_uint64(&in);
            ptr_info[n_ptr].parse = parse_struct_SpiceImage;
            ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
            n_ptr++;
        }
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_draw_blend(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[3];
    size_t base__extra_size;
    size_t data__extra_size;
    SpiceMsgDisplayDrawBlend *out;
    uint32_t i;

    { /* base */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
        size_t base_clip__extra_size;
        { /* clip */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
            size_t base_clip_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_CLIP_TYPE_RECTS) {
                    uint64_t base_clip_u_rects__value;
                    pos = (start3 + 4);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    base_clip_u_rects__value = read_uint64(pos);
                    ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
                } else if (1) {
                    base_clip_u__extra_size = 0;
                } else {
                    base_clip_u__extra_size = 0;
                }

            }

            base_clip__extra_size = base_clip_u__extra_size;
        }

        base__extra_size = base_clip__extra_size;
    }

    { /* data */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
        size_t data_src_bitmap__extra_size;
        size_t data_mask__extra_size;
        { /* src_bitmap */
            uint64_t src_bitmap__value;
            pos = (start2 + 0);
            if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                goto error;
            }
            src_bitmap__value = read_uint64(pos);
            ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
            if (SPICE_UNLIKELY(ptr_size < 0)) {
                goto error;
            }
            data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
        }

        { /* mask */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 27);
            size_t data_mask_bitmap__extra_size;
            { /* bitmap */
                uint64_t bitmap__value;
                pos = (start3 + 9);
                if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                    goto error;
                }
                bitmap__value = read_uint64(pos);
                ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
                if (SPICE_UNLIKELY(ptr_size < 0)) {
                    goto error;
                }
                data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
            }

            data_mask__extra_size = data_mask_bitmap__extra_size;
        }

        data__extra_size = data_src_bitmap__extra_size + data_mask__extra_size;
    }

    nw_size = 72;
    mem_size = sizeof(SpiceMsgDisplayDrawBlend) + base__extra_size + data__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayDrawBlend);
    in = start;

    out = (SpiceMsgDisplayDrawBlend *)data;

    /* base */ {
        out->base.surface_id = 0;
        /* box */ {
            out->base.box.top = consume_int32(&in);
            out->base.box.left = consume_int32(&in);
            out->base.box.bottom = consume_int32(&in);
            out->base.box.right = consume_int32(&in);
        }
        /* clip */ {
            out->base.clip.type = consume_uint32(&in);
            if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
                ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
                n_ptr++;
            } else if (1) {
                consume_uint64(&in);
            }
        }
    }
    /* data */ {
        ptr_info[n_ptr].offset = consume_uint64(&in);
        ptr_info[n_ptr].parse = parse_struct_SpiceImage;
        ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
        n_ptr++;
        /* src_area */ {
            out->data.src_area.top = consume_int32(&in);
            out->data.src_area.left = consume_int32(&in);
            out->data.src_area.bottom = consume_int32(&in);
            out->data.src_area.right = consume_int32(&in);
        }
        out->data.rop_descriptor = consume_uint16(&in);
        out->data.scale_mode = consume_uint8(&in);
        /* mask */ {
            out->data.mask.flags = consume_uint8(&in);
            /* pos */ {
                out->data.mask.pos.x = consume_int32(&in);
                out->data.mask.pos.y = consume_int32(&in);
            }
            ptr_info[n_ptr].offset = consume_uint64(&in);
            ptr_info[n_ptr].parse = parse_struct_SpiceImage;
            ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
            n_ptr++;
        }
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_draw_blackness(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[2];
    size_t base__extra_size;
    size_t data__extra_size;
    SpiceMsgDisplayDrawBlackness *out;
    uint32_t i;

    { /* base */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
        size_t base_clip__extra_size;
        { /* clip */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
            size_t base_clip_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_CLIP_TYPE_RECTS) {
                    uint64_t base_clip_u_rects__value;
                    pos = (start3 + 4);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    base_clip_u_rects__value = read_uint64(pos);
                    ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
                } else if (1) {
                    base_clip_u__extra_size = 0;
                } else {
                    base_clip_u__extra_size = 0;
                }

            }

            base_clip__extra_size = base_clip_u__extra_size;
        }

        base__extra_size = base_clip__extra_size;
    }

    { /* data */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
        size_t data_mask__extra_size;
        { /* mask */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
            size_t data_mask_bitmap__extra_size;
            { /* bitmap */
                uint64_t bitmap__value;
                pos = (start3 + 9);
                if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                    goto error;
                }
                bitmap__value = read_uint64(pos);
                ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
                if (SPICE_UNLIKELY(ptr_size < 0)) {
                    goto error;
                }
                data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
            }

            data_mask__extra_size = data_mask_bitmap__extra_size;
        }

        data__extra_size = data_mask__extra_size;
    }

    nw_size = 45;
    mem_size = sizeof(SpiceMsgDisplayDrawBlackness) + base__extra_size + data__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayDrawBlackness);
    in = start;

    out = (SpiceMsgDisplayDrawBlackness *)data;

    /* base */ {
        out->base.surface_id = 0;
        /* box */ {
            out->base.box.top = consume_int32(&in);
            out->base.box.left = consume_int32(&in);
            out->base.box.bottom = consume_int32(&in);
            out->base.box.right = consume_int32(&in);
        }
        /* clip */ {
            out->base.clip.type = consume_uint32(&in);
            if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
                ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
                n_ptr++;
            } else if (1) {
                consume_uint64(&in);
            }
        }
    }
    /* data */ {
        /* mask */ {
            out->data.mask.flags = consume_uint8(&in);
            /* pos */ {
                out->data.mask.pos.x = consume_int32(&in);
                out->data.mask.pos.y = consume_int32(&in);
            }
            ptr_info[n_ptr].offset = consume_uint64(&in);
            ptr_info[n_ptr].parse = parse_struct_SpiceImage;
            ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
            n_ptr++;
        }
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_draw_whiteness(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[2];
    size_t base__extra_size;
    size_t data__extra_size;
    SpiceMsgDisplayDrawWhiteness *out;
    uint32_t i;

    { /* base */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
        size_t base_clip__extra_size;
        { /* clip */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
            size_t base_clip_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_CLIP_TYPE_RECTS) {
                    uint64_t base_clip_u_rects__value;
                    pos = (start3 + 4);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    base_clip_u_rects__value = read_uint64(pos);
                    ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
                } else if (1) {
                    base_clip_u__extra_size = 0;
                } else {
                    base_clip_u__extra_size = 0;
                }

            }

            base_clip__extra_size = base_clip_u__extra_size;
        }

        base__extra_size = base_clip__extra_size;
    }

    { /* data */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
        size_t data_mask__extra_size;
        { /* mask */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
            size_t data_mask_bitmap__extra_size;
            { /* bitmap */
                uint64_t bitmap__value;
                pos = (start3 + 9);
                if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                    goto error;
                }
                bitmap__value = read_uint64(pos);
                ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
                if (SPICE_UNLIKELY(ptr_size < 0)) {
                    goto error;
                }
                data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
            }

            data_mask__extra_size = data_mask_bitmap__extra_size;
        }

        data__extra_size = data_mask__extra_size;
    }

    nw_size = 45;
    mem_size = sizeof(SpiceMsgDisplayDrawWhiteness) + base__extra_size + data__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayDrawWhiteness);
    in = start;

    out = (SpiceMsgDisplayDrawWhiteness *)data;

    /* base */ {
        out->base.surface_id = 0;
        /* box */ {
            out->base.box.top = consume_int32(&in);
            out->base.box.left = consume_int32(&in);
            out->base.box.bottom = consume_int32(&in);
            out->base.box.right = consume_int32(&in);
        }
        /* clip */ {
            out->base.clip.type = consume_uint32(&in);
            if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
                ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
                n_ptr++;
            } else if (1) {
                consume_uint64(&in);
            }
        }
    }
    /* data */ {
        /* mask */ {
            out->data.mask.flags = consume_uint8(&in);
            /* pos */ {
                out->data.mask.pos.x = consume_int32(&in);
                out->data.mask.pos.y = consume_int32(&in);
            }
            ptr_info[n_ptr].offset = consume_uint64(&in);
            ptr_info[n_ptr].parse = parse_struct_SpiceImage;
            ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
            n_ptr++;
        }
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_draw_invers(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[2];
    size_t base__extra_size;
    size_t data__extra_size;
    SpiceMsgDisplayDrawInvers *out;
    uint32_t i;

    { /* base */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
        size_t base_clip__extra_size;
        { /* clip */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
            size_t base_clip_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_CLIP_TYPE_RECTS) {
                    uint64_t base_clip_u_rects__value;
                    pos = (start3 + 4);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    base_clip_u_rects__value = read_uint64(pos);
                    ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
                } else if (1) {
                    base_clip_u__extra_size = 0;
                } else {
                    base_clip_u__extra_size = 0;
                }

            }

            base_clip__extra_size = base_clip_u__extra_size;
        }

        base__extra_size = base_clip__extra_size;
    }

    { /* data */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
        size_t data_mask__extra_size;
        { /* mask */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
            size_t data_mask_bitmap__extra_size;
            { /* bitmap */
                uint64_t bitmap__value;
                pos = (start3 + 9);
                if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                    goto error;
                }
                bitmap__value = read_uint64(pos);
                ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
                if (SPICE_UNLIKELY(ptr_size < 0)) {
                    goto error;
                }
                data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
            }

            data_mask__extra_size = data_mask_bitmap__extra_size;
        }

        data__extra_size = data_mask__extra_size;
    }

    nw_size = 45;
    mem_size = sizeof(SpiceMsgDisplayDrawInvers) + base__extra_size + data__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayDrawInvers);
    in = start;

    out = (SpiceMsgDisplayDrawInvers *)data;

    /* base */ {
        out->base.surface_id = 0;
        /* box */ {
            out->base.box.top = consume_int32(&in);
            out->base.box.left = consume_int32(&in);
            out->base.box.bottom = consume_int32(&in);
            out->base.box.right = consume_int32(&in);
        }
        /* clip */ {
            out->base.clip.type = consume_uint32(&in);
            if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
                ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
                n_ptr++;
            } else if (1) {
                consume_uint64(&in);
            }
        }
    }
    /* data */ {
        /* mask */ {
            out->data.mask.flags = consume_uint8(&in);
            /* pos */ {
                out->data.mask.pos.x = consume_int32(&in);
                out->data.mask.pos.y = consume_int32(&in);
            }
            ptr_info[n_ptr].offset = consume_uint64(&in);
            ptr_info[n_ptr].parse = parse_struct_SpiceImage;
            ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
            n_ptr++;
        }
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_draw_rop3(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[4];
    size_t base__extra_size;
    size_t data__extra_size;
    SpiceMsgDisplayDrawRop3 *out;
    uint32_t i;

    { /* base */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
        size_t base_clip__extra_size;
        { /* clip */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
            size_t base_clip_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_CLIP_TYPE_RECTS) {
                    uint64_t base_clip_u_rects__value;
                    pos = (start3 + 4);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    base_clip_u_rects__value = read_uint64(pos);
                    ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
                } else if (1) {
                    base_clip_u__extra_size = 0;
                } else {
                    base_clip_u__extra_size = 0;
                }

            }

            base_clip__extra_size = base_clip_u__extra_size;
        }

        base__extra_size = base_clip__extra_size;
    }

    { /* data */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
        size_t data_src_bitmap__extra_size;
        size_t data_brush__extra_size;
        size_t data_mask__extra_size;
        { /* src_bitmap */
            uint64_t src_bitmap__value;
            pos = (start2 + 0);
            if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                goto error;
            }
            src_bitmap__value = read_uint64(pos);
            ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
            if (SPICE_UNLIKELY(ptr_size < 0)) {
                goto error;
            }
            data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
        }

        { /* brush */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 24);
            size_t data_brush_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_BRUSH_TYPE_SOLID) {
                    data_brush_u__extra_size = 0;
                } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
                    SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 4);
                    size_t data_brush_u_pat__extra_size;
                    { /* pat */
                        uint64_t pat__value;
                        pos = (start4 + 0);
                        if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                            goto error;
                        }
                        pat__value = read_uint64(pos);
                        if (SPICE_UNLIKELY(pat__value == 0)) {
                            goto error;
                        }
                        ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
                        if (SPICE_UNLIKELY(ptr_size < 0)) {
                            goto error;
                        }
                        data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
                    }

                    data_brush_u__extra_size = data_brush_u_pat__extra_size;
                } else {
                    data_brush_u__extra_size = 0;
                }

            }

            data_brush__extra_size = data_brush_u__extra_size;
        }

        { /* mask */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 46);
            size_t data_mask_bitmap__extra_size;
            { /* bitmap */
                uint64_t bitmap__value;
                pos = (start3 + 9);
                if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                    goto error;
                }
                bitmap__value = read_uint64(pos);
                ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
                if (SPICE_UNLIKELY(ptr_size < 0)) {
                    goto error;
                }
                data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
            }

            data_mask__extra_size = data_mask_bitmap__extra_size;
        }

        data__extra_size = data_src_bitmap__extra_size + data_brush__extra_size + data_mask__extra_size;
    }

    nw_size = 91;
    mem_size = sizeof(SpiceMsgDisplayDrawRop3) + base__extra_size + data__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayDrawRop3);
    in = start;

    out = (SpiceMsgDisplayDrawRop3 *)data;

    /* base */ {
        out->base.surface_id = 0;
        /* box */ {
            out->base.box.top = consume_int32(&in);
            out->base.box.left = consume_int32(&in);
            out->base.box.bottom = consume_int32(&in);
            out->base.box.right = consume_int32(&in);
        }
        /* clip */ {
            out->base.clip.type = consume_uint32(&in);
            if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
                ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
                n_ptr++;
            } else if (1) {
                consume_uint64(&in);
            }
        }
    }
    /* data */ {
        ptr_info[n_ptr].offset = consume_uint64(&in);
        ptr_info[n_ptr].parse = parse_struct_SpiceImage;
        ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
        n_ptr++;
        /* src_area */ {
            out->data.src_area.top = consume_int32(&in);
            out->data.src_area.left = consume_int32(&in);
            out->data.src_area.bottom = consume_int32(&in);
            out->data.src_area.right = consume_int32(&in);
        }
        /* brush */ {
            uint8_t *in_save;
            out->data.brush.type = consume_uint32(&in);
            in_save = in;
            if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
                out->data.brush.u.color = consume_uint32(&in);
            } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceImage;
                ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
                n_ptr++;
                /* pos */ {
                    out->data.brush.u.pattern.pos.x = consume_int32(&in);
                    out->data.brush.u.pattern.pos.y = consume_int32(&in);
                }
            }
            in = in_save + 16;
        }
        out->data.rop3 = consume_uint8(&in);
        out->data.scale_mode = consume_uint8(&in);
        /* mask */ {
            out->data.mask.flags = consume_uint8(&in);
            /* pos */ {
                out->data.mask.pos.x = consume_int32(&in);
                out->data.mask.pos.y = consume_int32(&in);
            }
            ptr_info[n_ptr].offset = consume_uint64(&in);
            ptr_info[n_ptr].parse = parse_struct_SpiceImage;
            ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
            n_ptr++;
        }
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static intptr_t validate_SpicePath(uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor)
{
    uint8_t *start = message_start + offset;
    SPICE_GNUC_UNUSED uint8_t *pos;
    size_t mem_size, nw_size;
    size_t segments__nw_size, segments__mem_size;
    uint32_t segments__nelements;
    uint32_t segments__nbytes;

    if (offset == 0) {
        return 0;
    }

    if (SPICE_UNLIKELY(start >= message_end)) {
        goto error;
    }

    { /* segments */
        uint32_t segments_size__value;
        uint8_t *start2 = (start + 4);
        uint8_t *start2_array_end;
        uint32_t segments__element__nw_size;
        uint32_t segments__element__mem_size;
        pos = start + 0;
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        segments_size__value = read_uint32(pos);
        segments__nbytes = segments_size__value;
        segments__nelements = 0;

        segments__nw_size = segments__nbytes;
        segments__mem_size = 0;
        start2_array_end = start2 + segments__nbytes;
        while (start2 < start2_array_end) {
            SPICE_GNUC_UNUSED uint8_t *start3 = start2;
            size_t segments__element_points__nw_size, segments__element_points__mem_size;
            uint32_t segments__element_points__nelements;
            segments__nelements += 1;
            { /* points */
                uint32_t count__value;
                pos = start3 + 4;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                count__value = read_uint32(pos);
                segments__element_points__nelements = count__value;

                segments__element_points__nw_size = (8) * segments__element_points__nelements;
                segments__element_points__mem_size = sizeof(SpicePointFix) * segments__element_points__nelements;
            }

            segments__element__nw_size = 8 + segments__element_points__nw_size;
            segments__element__mem_size = sizeof(SpicePathSeg) + segments__element_points__mem_size;
            segments__mem_size += sizeof(void *) + SPICE_ALIGN(segments__element__mem_size, 4);
            start2 += segments__element__nw_size;
        }
        if (SPICE_UNLIKELY(start2 != start2_array_end)) {
            goto error;
        }
        pos = start + 0;
        write_uint32(pos, segments__nelements);
    }

    nw_size = 4 + segments__nw_size;
    mem_size = sizeof(SpicePath) + segments__mem_size;

    /* Check if struct fits in reported side */
    if (SPICE_UNLIKELY(start + nw_size > message_end)) {
        goto error;
    }
    return mem_size;

   error:
    return -1;
}

static uint8_t * parse_struct_SpicePath(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
{
    uint8_t *in = message_start + this_ptr_info->offset;
    uint8_t *end;
    SpicePath *out;
    uint32_t segments__nelements;
    uint32_t i;
    void * *ptr_array;
    int ptr_array_index;
    uint32_t j;

    end = struct_data + sizeof(SpicePath);
    out = (SpicePath *)struct_data;

    out->num_segments = consume_uint32(&in);
    segments__nelements = out->num_segments;
    ptr_array_index = 0;
    ptr_array = (void **)out->segments;
    end += sizeof(void *) * segments__nelements;
    for (i = 0; i < segments__nelements; i++) {
        SpicePathSeg *out2;
        uint32_t points__nelements;
        ptr_array[ptr_array_index++] = end;
        out2 = (SpicePathSeg *)end;
        end += sizeof(SpicePathSeg);

        out2->flags = consume_uint32(&in);
        out2->count = consume_uint32(&in);
        points__nelements = out2->count;
        for (j = 0; j < points__nelements; j++) {
            SpicePointFix *out3;
            out3 = (SpicePointFix *)end;
            end += sizeof(SpicePointFix);

            out3->x = consume_int32(&in);
            out3->y = consume_int32(&in);
        }
        /* Align ptr_array element to 4 bytes */
        end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
    }
    return end;
}

static uint8_t * parse_array_int32(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
{
    uint8_t *in = message_start + this_ptr_info->offset;
    uint8_t *end;
    uint32_t i;

    end = struct_data;
    for (i = 0; i < this_ptr_info->nelements; i++) {
        *(SPICE_FIXED28_4 *)end = consume_int32(&in);
        end += sizeof(SPICE_FIXED28_4);
    }
    return end;
}

static uint8_t * parse_msg_display_draw_stroke(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[4];
    size_t base__extra_size;
    size_t data__extra_size;
    SpiceMsgDisplayDrawStroke *out;
    uint32_t i;

    { /* base */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
        size_t base_clip__extra_size;
        { /* clip */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
            size_t base_clip_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_CLIP_TYPE_RECTS) {
                    uint64_t base_clip_u_rects__value;
                    pos = (start3 + 4);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    base_clip_u_rects__value = read_uint64(pos);
                    ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
                } else if (1) {
                    base_clip_u__extra_size = 0;
                } else {
                    base_clip_u__extra_size = 0;
                }

            }

            base_clip__extra_size = base_clip_u__extra_size;
        }

        base__extra_size = base_clip__extra_size;
    }

    { /* data */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
        size_t data_path__extra_size;
        size_t data_attr__extra_size;
        size_t data_brush__extra_size;
        { /* path */
            uint64_t path__value;
            pos = (start2 + 0);
            if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                goto error;
            }
            path__value = read_uint64(pos);
            ptr_size = validate_SpicePath(message_start, message_end, path__value, minor);
            if (SPICE_UNLIKELY(ptr_size < 0)) {
                goto error;
            }
            data_path__extra_size = ptr_size + /* for alignment */ 3;
        }

        { /* attr */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 8);
            size_t data_attr_style__extra_size;
            uint32_t data_attr_style__array__nelements;
            { /* style */
                uint64_t style__value;
                uint32_t data_attr_style__array__nw_size;
                uint32_t data_attr_style__array__mem_size;
                uint8_t style_nseg__value;
                pos = (start3 + 12);
                if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                    goto error;
                }
                style__value = read_uint64(pos);
                if (SPICE_UNLIKELY(message_start + style__value >= message_end)) {
                    goto error;
                }
                pos = start3 + 3;
                if (SPICE_UNLIKELY(pos + 1 > message_end)) {
                    goto error;
                }
                style_nseg__value = read_uint8(pos);
                data_attr_style__array__nelements = style_nseg__value;

                data_attr_style__array__nw_size = (4) * data_attr_style__array__nelements;
                data_attr_style__array__mem_size = sizeof(SPICE_FIXED28_4) * data_attr_style__array__nelements;
                if (SPICE_UNLIKELY(message_start + style__value + data_attr_style__array__nw_size > message_end)) {
                    goto error;
                }
                data_attr_style__extra_size = data_attr_style__array__mem_size + /* for alignment */ 3;
            }

            data_attr__extra_size = data_attr_style__extra_size;
        }

        { /* brush */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 28);
            size_t data_brush_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_BRUSH_TYPE_SOLID) {
                    data_brush_u__extra_size = 0;
                } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
                    SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 4);
                    size_t data_brush_u_pat__extra_size;
                    { /* pat */
                        uint64_t pat__value;
                        pos = (start4 + 0);
                        if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                            goto error;
                        }
                        pat__value = read_uint64(pos);
                        if (SPICE_UNLIKELY(pat__value == 0)) {
                            goto error;
                        }
                        ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
                        if (SPICE_UNLIKELY(ptr_size < 0)) {
                            goto error;
                        }
                        data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
                    }

                    data_brush_u__extra_size = data_brush_u_pat__extra_size;
                } else {
                    data_brush_u__extra_size = 0;
                }

            }

            data_brush__extra_size = data_brush_u__extra_size;
        }

        data__extra_size = data_path__extra_size + data_attr__extra_size + data_brush__extra_size;
    }

    nw_size = 80;
    mem_size = sizeof(SpiceMsgDisplayDrawStroke) + base__extra_size + data__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayDrawStroke);
    in = start;

    out = (SpiceMsgDisplayDrawStroke *)data;

    /* base */ {
        out->base.surface_id = 0;
        /* box */ {
            out->base.box.top = consume_int32(&in);
            out->base.box.left = consume_int32(&in);
            out->base.box.bottom = consume_int32(&in);
            out->base.box.right = consume_int32(&in);
        }
        /* clip */ {
            out->base.clip.type = consume_uint32(&in);
            if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
                ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
                n_ptr++;
            } else if (1) {
                consume_uint64(&in);
            }
        }
    }
    /* data */ {
        ptr_info[n_ptr].offset = consume_uint64(&in);
        ptr_info[n_ptr].parse = parse_struct_SpicePath;
        ptr_info[n_ptr].dest = (void **)&out->data.path;
        n_ptr++;
        /* attr */ {
            uint32_t style__array__nelements;
            out->data.attr.flags = consume_uint8(&in);
            consume_uint8(&in);
            consume_uint8(&in);
            out->data.attr.style_nseg = consume_uint8(&in);
            consume_int32(&in);
            consume_int32(&in);
            ptr_info[n_ptr].offset = consume_uint64(&in);
            ptr_info[n_ptr].parse = parse_array_int32;
            ptr_info[n_ptr].dest = (void **)&out->data.attr.style;
            style__array__nelements = out->data.attr.style_nseg;
            ptr_info[n_ptr].nelements = style__array__nelements;
            n_ptr++;
        }
        /* brush */ {
            uint8_t *in_save;
            out->data.brush.type = consume_uint32(&in);
            in_save = in;
            if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
                out->data.brush.u.color = consume_uint32(&in);
            } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceImage;
                ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
                n_ptr++;
                /* pos */ {
                    out->data.brush.u.pattern.pos.x = consume_int32(&in);
                    out->data.brush.u.pattern.pos.y = consume_int32(&in);
                }
            }
            in = in_save + 16;
        }
        out->data.fore_mode = consume_uint16(&in);
        out->data.back_mode = consume_uint16(&in);
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static intptr_t validate_SpiceString(uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor)
{
    uint8_t *start = message_start + offset;
    SPICE_GNUC_UNUSED uint8_t *pos;
    size_t mem_size, nw_size;
    size_t u__nw_size, u__extra_size;
    uint16_t flags__value;
    uint32_t i;

    if (offset == 0) {
        return 0;
    }

    if (SPICE_UNLIKELY(start >= message_end)) {
        goto error;
    }

    { /* u */
        uint32_t u__mem_size;
        uint32_t u__nelements;
        pos = start + 2;
        if (SPICE_UNLIKELY(pos + 2 > message_end)) {
            goto error;
        }
        flags__value = read_uint16(pos);
        if ((flags__value & SPICE_STRING_FLAGS_RASTER_A1)) {
            uint16_t length__value;
            uint8_t *start2 = (start + 4);
            uint32_t u__element__nw_size;
            uint32_t u__element__mem_size;
            pos = start + 0;
            if (SPICE_UNLIKELY(pos + 2 > message_end)) {
                goto error;
            }
            length__value = read_uint16(pos);
            u__nelements = length__value;

            u__nw_size = 0;
            u__mem_size = 0;
            for (i = 0; i < u__nelements; i++) {
                SPICE_GNUC_UNUSED uint8_t *start3 = start2;
                size_t u__element_data__nw_size, u__element_data__mem_size;
                uint32_t u__element_data__nelements;
                { /* data */
                    uint16_t width__value;
                    uint16_t height__value;
                    pos = start3 + 16;
                    if (SPICE_UNLIKELY(pos + 2 > message_end)) {
                        goto error;
                    }
                    width__value = read_uint16(pos);
                    pos = start3 + 18;
                    if (SPICE_UNLIKELY(pos + 2 > message_end)) {
                        goto error;
                    }
                    height__value = read_uint16(pos);
                    u__element_data__nelements = ((width__value + 7) / 8 ) * height__value;

                    u__element_data__nw_size = u__element_data__nelements;
                    u__element_data__mem_size = sizeof(uint8_t) * u__element_data__nelements;
                }

                u__element__nw_size = 20 + u__element_data__nw_size;
                u__element__mem_size = sizeof(SpiceRasterGlyph) + u__element_data__mem_size;
                u__nw_size += u__element__nw_size;
                u__mem_size += sizeof(void *) + SPICE_ALIGN(u__element__mem_size, 4);
                start2 += u__element__nw_size;
            }
            u__extra_size = u__mem_size;
        } else if ((flags__value & SPICE_STRING_FLAGS_RASTER_A4)) {
            uint16_t length__value;
            uint8_t *start2 = (start + 4);
            uint32_t u__element__nw_size;
            uint32_t u__element__mem_size;
            pos = start + 0;
            if (SPICE_UNLIKELY(pos + 2 > message_end)) {
                goto error;
            }
            length__value = read_uint16(pos);
            u__nelements = length__value;

            u__nw_size = 0;
            u__mem_size = 0;
            for (i = 0; i < u__nelements; i++) {
                SPICE_GNUC_UNUSED uint8_t *start3 = start2;
                size_t u__element_data__nw_size, u__element_data__mem_size;
                uint32_t u__element_data__nelements;
                { /* data */
                    uint16_t width__value;
                    uint16_t height__value;
                    pos = start3 + 16;
                    if (SPICE_UNLIKELY(pos + 2 > message_end)) {
                        goto error;
                    }
                    width__value = read_uint16(pos);
                    pos = start3 + 18;
                    if (SPICE_UNLIKELY(pos + 2 > message_end)) {
                        goto error;
                    }
                    height__value = read_uint16(pos);
                    u__element_data__nelements = ((4 * width__value + 7) / 8 ) * height__value;

                    u__element_data__nw_size = u__element_data__nelements;
                    u__element_data__mem_size = sizeof(uint8_t) * u__element_data__nelements;
                }

                u__element__nw_size = 20 + u__element_data__nw_size;
                u__element__mem_size = sizeof(SpiceRasterGlyph) + u__element_data__mem_size;
                u__nw_size += u__element__nw_size;
                u__mem_size += sizeof(void *) + SPICE_ALIGN(u__element__mem_size, 4);
                start2 += u__element__nw_size;
            }
            u__extra_size = u__mem_size;
        } else if ((flags__value & SPICE_STRING_FLAGS_RASTER_A8)) {
            uint16_t length__value;
            uint8_t *start2 = (start + 4);
            uint32_t u__element__nw_size;
            uint32_t u__element__mem_size;
            pos = start + 0;
            if (SPICE_UNLIKELY(pos + 2 > message_end)) {
                goto error;
            }
            length__value = read_uint16(pos);
            u__nelements = length__value;

            u__nw_size = 0;
            u__mem_size = 0;
            for (i = 0; i < u__nelements; i++) {
                SPICE_GNUC_UNUSED uint8_t *start3 = start2;
                size_t u__element_data__nw_size, u__element_data__mem_size;
                uint32_t u__element_data__nelements;
                { /* data */
                    uint16_t width__value;
                    uint16_t height__value;
                    pos = start3 + 16;
                    if (SPICE_UNLIKELY(pos + 2 > message_end)) {
                        goto error;
                    }
                    width__value = read_uint16(pos);
                    pos = start3 + 18;
                    if (SPICE_UNLIKELY(pos + 2 > message_end)) {
                        goto error;
                    }
                    height__value = read_uint16(pos);
                    u__element_data__nelements = width__value * height__value;

                    u__element_data__nw_size = u__element_data__nelements;
                    u__element_data__mem_size = sizeof(uint8_t) * u__element_data__nelements;
                }

                u__element__nw_size = 20 + u__element_data__nw_size;
                u__element__mem_size = sizeof(SpiceRasterGlyph) + u__element_data__mem_size;
                u__nw_size += u__element__nw_size;
                u__mem_size += sizeof(void *) + SPICE_ALIGN(u__element__mem_size, 4);
                start2 += u__element__nw_size;
            }
            u__extra_size = u__mem_size;
        } else {
            u__nw_size = 0;
            u__extra_size = 0;
        }

    }

    nw_size = 4 + u__nw_size;
    mem_size = sizeof(SpiceString) + u__extra_size;

    /* Check if struct fits in reported side */
    if (SPICE_UNLIKELY(start + nw_size > message_end)) {
        goto error;
    }
    return mem_size;

   error:
    return -1;
}

static uint8_t * parse_struct_SpiceString(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
{
    uint8_t *in = message_start + this_ptr_info->offset;
    uint8_t *end;
    SpiceString *out;
    uint32_t i;

    end = struct_data + sizeof(SpiceString);
    out = (SpiceString *)struct_data;

    out->length = consume_uint16(&in);
    out->flags = consume_uint16(&in);
    if ((out->flags & SPICE_STRING_FLAGS_RASTER_A1)) {
        uint32_t glyphs__nelements;
        void * *ptr_array;
        int ptr_array_index;
        glyphs__nelements = out->length;
        ptr_array_index = 0;
        ptr_array = (void **)out->glyphs;
        end += sizeof(void *) * glyphs__nelements;
        for (i = 0; i < glyphs__nelements; i++) {
            SpiceRasterGlyph *out2;
            uint32_t data__nelements;
            ptr_array[ptr_array_index++] = end;
            out2 = (SpiceRasterGlyph *)end;
            end += sizeof(SpiceRasterGlyph);

            /* render_pos */ {
                out2->render_pos.x = consume_int32(&in);
                out2->render_pos.y = consume_int32(&in);
            }
            /* glyph_origin */ {
                out2->glyph_origin.x = consume_int32(&in);
                out2->glyph_origin.y = consume_int32(&in);
            }
            out2->width = consume_uint16(&in);
            out2->height = consume_uint16(&in);
            data__nelements = ((out2->width + 7) / 8 ) * out2->height;
            memcpy(out2->data, in, data__nelements);
            in += data__nelements;
            end += data__nelements;
            /* Align ptr_array element to 4 bytes */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
        }
    } else if ((out->flags & SPICE_STRING_FLAGS_RASTER_A4)) {
        uint32_t glyphs__nelements;
        void * *ptr_array;
        int ptr_array_index;
        glyphs__nelements = out->length;
        ptr_array_index = 0;
        ptr_array = (void **)out->glyphs;
        end += sizeof(void *) * glyphs__nelements;
        for (i = 0; i < glyphs__nelements; i++) {
            SpiceRasterGlyph *out2;
            uint32_t data__nelements;
            ptr_array[ptr_array_index++] = end;
            out2 = (SpiceRasterGlyph *)end;
            end += sizeof(SpiceRasterGlyph);

            /* render_pos */ {
                out2->render_pos.x = consume_int32(&in);
                out2->render_pos.y = consume_int32(&in);
            }
            /* glyph_origin */ {
                out2->glyph_origin.x = consume_int32(&in);
                out2->glyph_origin.y = consume_int32(&in);
            }
            out2->width = consume_uint16(&in);
            out2->height = consume_uint16(&in);
            data__nelements = ((4 * out2->width + 7) / 8 ) * out2->height;
            memcpy(out2->data, in, data__nelements);
            in += data__nelements;
            end += data__nelements;
            /* Align ptr_array element to 4 bytes */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
        }
    } else if ((out->flags & SPICE_STRING_FLAGS_RASTER_A8)) {
        uint32_t glyphs__nelements;
        void * *ptr_array;
        int ptr_array_index;
        glyphs__nelements = out->length;
        ptr_array_index = 0;
        ptr_array = (void **)out->glyphs;
        end += sizeof(void *) * glyphs__nelements;
        for (i = 0; i < glyphs__nelements; i++) {
            SpiceRasterGlyph *out2;
            uint32_t data__nelements;
            ptr_array[ptr_array_index++] = end;
            out2 = (SpiceRasterGlyph *)end;
            end += sizeof(SpiceRasterGlyph);

            /* render_pos */ {
                out2->render_pos.x = consume_int32(&in);
                out2->render_pos.y = consume_int32(&in);
            }
            /* glyph_origin */ {
                out2->glyph_origin.x = consume_int32(&in);
                out2->glyph_origin.y = consume_int32(&in);
            }
            out2->width = consume_uint16(&in);
            out2->height = consume_uint16(&in);
            data__nelements = out2->width * out2->height;
            memcpy(out2->data, in, data__nelements);
            in += data__nelements;
            end += data__nelements;
            /* Align ptr_array element to 4 bytes */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
        }
    }
    return end;
}

static uint8_t * parse_msg_display_draw_text(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[4];
    size_t base__extra_size;
    size_t data__extra_size;
    SpiceMsgDisplayDrawText *out;
    uint32_t i;

    { /* base */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
        size_t base_clip__extra_size;
        { /* clip */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
            size_t base_clip_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_CLIP_TYPE_RECTS) {
                    uint64_t base_clip_u_rects__value;
                    pos = (start3 + 4);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    base_clip_u_rects__value = read_uint64(pos);
                    ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
                } else if (1) {
                    base_clip_u__extra_size = 0;
                } else {
                    base_clip_u__extra_size = 0;
                }

            }

            base_clip__extra_size = base_clip_u__extra_size;
        }

        base__extra_size = base_clip__extra_size;
    }

    { /* data */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
        size_t data_str__extra_size;
        size_t data_fore_brush__extra_size;
        size_t data_back_brush__extra_size;
        { /* str */
            uint64_t str__value;
            pos = (start2 + 0);
            if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                goto error;
            }
            str__value = read_uint64(pos);
            ptr_size = validate_SpiceString(message_start, message_end, str__value, minor);
            if (SPICE_UNLIKELY(ptr_size < 0)) {
                goto error;
            }
            data_str__extra_size = ptr_size + /* for alignment */ 3;
        }

        { /* fore_brush */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 24);
            size_t data_fore_brush_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_BRUSH_TYPE_SOLID) {
                    data_fore_brush_u__extra_size = 0;
                } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
                    SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 4);
                    size_t data_fore_brush_u_pat__extra_size;
                    { /* pat */
                        uint64_t pat__value;
                        pos = (start4 + 0);
                        if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                            goto error;
                        }
                        pat__value = read_uint64(pos);
                        if (SPICE_UNLIKELY(pat__value == 0)) {
                            goto error;
                        }
                        ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
                        if (SPICE_UNLIKELY(ptr_size < 0)) {
                            goto error;
                        }
                        data_fore_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
                    }

                    data_fore_brush_u__extra_size = data_fore_brush_u_pat__extra_size;
                } else {
                    data_fore_brush_u__extra_size = 0;
                }

            }

            data_fore_brush__extra_size = data_fore_brush_u__extra_size;
        }

        { /* back_brush */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 44);
            size_t data_back_brush_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_BRUSH_TYPE_SOLID) {
                    data_back_brush_u__extra_size = 0;
                } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
                    SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 4);
                    size_t data_back_brush_u_pat__extra_size;
                    { /* pat */
                        uint64_t pat__value;
                        pos = (start4 + 0);
                        if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                            goto error;
                        }
                        pat__value = read_uint64(pos);
                        if (SPICE_UNLIKELY(pat__value == 0)) {
                            goto error;
                        }
                        ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
                        if (SPICE_UNLIKELY(ptr_size < 0)) {
                            goto error;
                        }
                        data_back_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
                    }

                    data_back_brush_u__extra_size = data_back_brush_u_pat__extra_size;
                } else {
                    data_back_brush_u__extra_size = 0;
                }

            }

            data_back_brush__extra_size = data_back_brush_u__extra_size;
        }

        data__extra_size = data_str__extra_size + data_fore_brush__extra_size + data_back_brush__extra_size;
    }

    nw_size = 96;
    mem_size = sizeof(SpiceMsgDisplayDrawText) + base__extra_size + data__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayDrawText);
    in = start;

    out = (SpiceMsgDisplayDrawText *)data;

    /* base */ {
        out->base.surface_id = 0;
        /* box */ {
            out->base.box.top = consume_int32(&in);
            out->base.box.left = consume_int32(&in);
            out->base.box.bottom = consume_int32(&in);
            out->base.box.right = consume_int32(&in);
        }
        /* clip */ {
            out->base.clip.type = consume_uint32(&in);
            if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
                ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
                n_ptr++;
            } else if (1) {
                consume_uint64(&in);
            }
        }
    }
    /* data */ {
        ptr_info[n_ptr].offset = consume_uint64(&in);
        ptr_info[n_ptr].parse = parse_struct_SpiceString;
        ptr_info[n_ptr].dest = (void **)&out->data.str;
        n_ptr++;
        /* back_area */ {
            out->data.back_area.top = consume_int32(&in);
            out->data.back_area.left = consume_int32(&in);
            out->data.back_area.bottom = consume_int32(&in);
            out->data.back_area.right = consume_int32(&in);
        }
        /* fore_brush */ {
            uint8_t *in_save;
            out->data.fore_brush.type = consume_uint32(&in);
            in_save = in;
            if (out->data.fore_brush.type == SPICE_BRUSH_TYPE_SOLID) {
                out->data.fore_brush.u.color = consume_uint32(&in);
            } else if (out->data.fore_brush.type == SPICE_BRUSH_TYPE_PATTERN) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceImage;
                ptr_info[n_ptr].dest = (void **)&out->data.fore_brush.u.pattern.pat;
                n_ptr++;
                /* pos */ {
                    out->data.fore_brush.u.pattern.pos.x = consume_int32(&in);
                    out->data.fore_brush.u.pattern.pos.y = consume_int32(&in);
                }
            }
            in = in_save + 16;
        }
        /* back_brush */ {
            uint8_t *in_save;
            out->data.back_brush.type = consume_uint32(&in);
            in_save = in;
            if (out->data.back_brush.type == SPICE_BRUSH_TYPE_SOLID) {
                out->data.back_brush.u.color = consume_uint32(&in);
            } else if (out->data.back_brush.type == SPICE_BRUSH_TYPE_PATTERN) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceImage;
                ptr_info[n_ptr].dest = (void **)&out->data.back_brush.u.pattern.pat;
                n_ptr++;
                /* pos */ {
                    out->data.back_brush.u.pattern.pos.x = consume_int32(&in);
                    out->data.back_brush.u.pattern.pos.y = consume_int32(&in);
                }
            }
            in = in_save + 16;
        }
        out->data.fore_mode = consume_uint16(&in);
        out->data.back_mode = consume_uint16(&in);
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_draw_transparent(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[2];
    size_t base__extra_size;
    size_t data__extra_size;
    SpiceMsgDisplayDrawTransparent *out;
    uint32_t i;

    { /* base */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
        size_t base_clip__extra_size;
        { /* clip */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
            size_t base_clip_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_CLIP_TYPE_RECTS) {
                    uint64_t base_clip_u_rects__value;
                    pos = (start3 + 4);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    base_clip_u_rects__value = read_uint64(pos);
                    ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
                } else if (1) {
                    base_clip_u__extra_size = 0;
                } else {
                    base_clip_u__extra_size = 0;
                }

            }

            base_clip__extra_size = base_clip_u__extra_size;
        }

        base__extra_size = base_clip__extra_size;
    }

    { /* data */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
        size_t data_src_bitmap__extra_size;
        { /* src_bitmap */
            uint64_t src_bitmap__value;
            pos = (start2 + 0);
            if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                goto error;
            }
            src_bitmap__value = read_uint64(pos);
            ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
            if (SPICE_UNLIKELY(ptr_size < 0)) {
                goto error;
            }
            data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
        }

        data__extra_size = data_src_bitmap__extra_size;
    }

    nw_size = 60;
    mem_size = sizeof(SpiceMsgDisplayDrawTransparent) + base__extra_size + data__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayDrawTransparent);
    in = start;

    out = (SpiceMsgDisplayDrawTransparent *)data;

    /* base */ {
        out->base.surface_id = 0;
        /* box */ {
            out->base.box.top = consume_int32(&in);
            out->base.box.left = consume_int32(&in);
            out->base.box.bottom = consume_int32(&in);
            out->base.box.right = consume_int32(&in);
        }
        /* clip */ {
            out->base.clip.type = consume_uint32(&in);
            if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
                ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
                n_ptr++;
            } else if (1) {
                consume_uint64(&in);
            }
        }
    }
    /* data */ {
        ptr_info[n_ptr].offset = consume_uint64(&in);
        ptr_info[n_ptr].parse = parse_struct_SpiceImage;
        ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
        n_ptr++;
        /* src_area */ {
            out->data.src_area.top = consume_int32(&in);
            out->data.src_area.left = consume_int32(&in);
            out->data.src_area.bottom = consume_int32(&in);
            out->data.src_area.right = consume_int32(&in);
        }
        out->data.src_color = consume_uint32(&in);
        out->data.true_color = consume_uint32(&in);
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_display_draw_alpha_blend(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[2];
    size_t base__extra_size;
    size_t data__extra_size;
    SpiceMsgDisplayDrawAlphaBlend *out;
    uint32_t i;

    { /* base */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
        size_t base_clip__extra_size;
        { /* clip */
            SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
            size_t base_clip_u__extra_size;
            uint32_t type__value;
            { /* u */
                pos = start3 + 0;
                if (SPICE_UNLIKELY(pos + 4 > message_end)) {
                    goto error;
                }
                type__value = read_uint32(pos);
                if (type__value == SPICE_CLIP_TYPE_RECTS) {
                    uint64_t base_clip_u_rects__value;
                    pos = (start3 + 4);
                    if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                        goto error;
                    }
                    base_clip_u_rects__value = read_uint64(pos);
                    ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
                    if (SPICE_UNLIKELY(ptr_size < 0)) {
                        goto error;
                    }
                    base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
                } else if (1) {
                    base_clip_u__extra_size = 0;
                } else {
                    base_clip_u__extra_size = 0;
                }

            }

            base_clip__extra_size = base_clip_u__extra_size;
        }

        base__extra_size = base_clip__extra_size;
    }

    { /* data */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
        size_t data_src_bitmap__extra_size;
        { /* src_bitmap */
            uint64_t src_bitmap__value;
            pos = (start2 + 1);
            if (SPICE_UNLIKELY(pos + 8 > message_end)) {
                goto error;
            }
            src_bitmap__value = read_uint64(pos);
            ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
            if (SPICE_UNLIKELY(ptr_size < 0)) {
                goto error;
            }
            data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
        }

        data__extra_size = data_src_bitmap__extra_size;
    }

    nw_size = 53;
    mem_size = sizeof(SpiceMsgDisplayDrawAlphaBlend) + base__extra_size + data__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayDrawAlphaBlend);
    in = start;

    out = (SpiceMsgDisplayDrawAlphaBlend *)data;

    /* base */ {
        out->base.surface_id = 0;
        /* box */ {
            out->base.box.top = consume_int32(&in);
            out->base.box.left = consume_int32(&in);
            out->base.box.bottom = consume_int32(&in);
            out->base.box.right = consume_int32(&in);
        }
        /* clip */ {
            out->base.clip.type = consume_uint32(&in);
            if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
                ptr_info[n_ptr].offset = consume_uint64(&in);
                ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
                ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
                n_ptr++;
            } else if (1) {
                consume_uint64(&in);
            }
        }
    }
    /* data */ {
        out->data.alpha_flags = 0;
        out->data.alpha = consume_uint8(&in);
        ptr_info[n_ptr].offset = consume_uint64(&in);
        ptr_info[n_ptr].parse = parse_struct_SpiceImage;
        ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
        n_ptr++;
        /* src_area */ {
            out->data.src_area.top = consume_int32(&in);
            out->data.src_area.left = consume_int32(&in);
            out->data.src_area.bottom = consume_int32(&in);
            out->data.src_area.right = consume_int32(&in);
        }
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_DisplayChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
{
    static parse_msg_func_t funcs1[7] =  {
        parse_msg_migrate,
        parse_SpiceMsgData,
        parse_msg_set_ack,
        parse_msg_ping,
        parse_msg_wait_for_channels,
        parse_msg_disconnecting,
        parse_msg_notify
    };
    static parse_msg_func_t funcs2[8] =  {
        parse_msg_display_mode,
        parse_SpiceMsgEmpty,
        parse_SpiceMsgEmpty,
        parse_msg_display_copy_bits,
        parse_msg_display_inval_list,
        parse_msg_display_inval_all_pixmaps,
        parse_msg_display_inval_palette,
        parse_SpiceMsgEmpty
    };
    static parse_msg_func_t funcs3[5] =  {
        parse_msg_display_stream_create,
        parse_msg_display_stream_data,
        parse_msg_display_stream_clip,
        parse_msg_display_stream_destroy,
        parse_SpiceMsgEmpty
    };
    static parse_msg_func_t funcs4[12] =  {
        parse_msg_display_draw_fill,
        parse_msg_display_draw_opaque,
        parse_msg_display_draw_copy,
        parse_msg_display_draw_blend,
        parse_msg_display_draw_blackness,
        parse_msg_display_draw_whiteness,
        parse_msg_display_draw_invers,
        parse_msg_display_draw_rop3,
        parse_msg_display_draw_stroke,
        parse_msg_display_draw_text,
        parse_msg_display_draw_transparent,
        parse_msg_display_draw_alpha_blend
    };
    if (message_type >= 1 && message_type < 8) {
        return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
    } else if (message_type >= 101 && message_type < 109) {
        return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
    } else if (message_type >= 122 && message_type < 127) {
        return funcs3[message_type-122](message_start, message_end, minor, size_out, free_message);
    } else if (message_type >= 302 && message_type < 314) {
        return funcs4[message_type-302](message_start, message_end, minor, size_out, free_message);
    }
    return NULL;
}



static uint8_t * parse_msg_inputs_init(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgInputsInit *out;

    nw_size = 4;
    mem_size = sizeof(SpiceMsgInputsInit);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgInputsInit);
    in = start;

    out = (SpiceMsgInputsInit *)data;

    out->keyboard_modifiers = consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_inputs_key_modifiers(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgInputsKeyModifiers *out;

    nw_size = 4;
    mem_size = sizeof(SpiceMsgInputsKeyModifiers);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgInputsKeyModifiers);
    in = start;

    out = (SpiceMsgInputsKeyModifiers *)data;

    out->modifiers = consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_InputsChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
{
    static parse_msg_func_t funcs1[7] =  {
        parse_msg_migrate,
        parse_SpiceMsgData,
        parse_msg_set_ack,
        parse_msg_ping,
        parse_msg_wait_for_channels,
        parse_msg_disconnecting,
        parse_msg_notify
    };
    static parse_msg_func_t funcs2[2] =  {
        parse_msg_inputs_init,
        parse_msg_inputs_key_modifiers
    };
    static parse_msg_func_t funcs3[1] =  {
        parse_SpiceMsgEmpty
    };
    if (message_type >= 1 && message_type < 8) {
        return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
    } else if (message_type >= 101 && message_type < 103) {
        return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
    } else if (message_type >= 111 && message_type < 112) {
        return funcs3[message_type-111](message_start, message_end, minor, size_out, free_message);
    }
    return NULL;
}



static uint8_t * parse_msg_cursor_init(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    size_t cursor__nw_size;
    SpiceMsgCursorInit *out;

    { /* cursor */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 9);
        size_t cursor_data__nw_size;
        uint32_t cursor_data__nelements;
        { /* data */
            cursor_data__nelements = message_end - (start2 + 22);

            cursor_data__nw_size = cursor_data__nelements;
        }

        cursor__nw_size = 22 + cursor_data__nw_size;
    }

    nw_size = 9 + cursor__nw_size;
    mem_size = sizeof(SpiceMsgCursorInit);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgCursorInit);
    in = start;

    out = (SpiceMsgCursorInit *)data;

    /* position */ {
        out->position.x = consume_int16(&in);
        out->position.y = consume_int16(&in);
    }
    out->trail_length = consume_uint16(&in);
    out->trail_frequency = consume_uint16(&in);
    out->visible = consume_uint8(&in);
    /* cursor */ {
        uint32_t data__nelements;
        out->cursor.flags = consume_uint32(&in);
        /* header */ {
            out->cursor.header.unique = consume_uint64(&in);
            out->cursor.header.type = consume_uint16(&in);
            out->cursor.header.width = consume_uint16(&in);
            out->cursor.header.height = consume_uint16(&in);
            out->cursor.header.hot_spot_x = consume_uint16(&in);
            out->cursor.header.hot_spot_y = consume_uint16(&in);
        }
        data__nelements = (message_end - in) / (1);
        /* use array as pointer */
        out->cursor.data = (uint8_t *)in;
        out->cursor.data_size = data__nelements;
        in += data__nelements;
    }

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_cursor_set(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    size_t cursor__nw_size;
    SpiceMsgCursorSet *out;

    { /* cursor */
        SPICE_GNUC_UNUSED uint8_t *start2 = (start + 5);
        size_t cursor_data__nw_size;
        uint32_t cursor_data__nelements;
        { /* data */
            cursor_data__nelements = message_end - (start2 + 22);

            cursor_data__nw_size = cursor_data__nelements;
        }

        cursor__nw_size = 22 + cursor_data__nw_size;
    }

    nw_size = 5 + cursor__nw_size;
    mem_size = sizeof(SpiceMsgCursorSet);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgCursorSet);
    in = start;

    out = (SpiceMsgCursorSet *)data;

    /* position */ {
        out->position.x = consume_int16(&in);
        out->position.y = consume_int16(&in);
    }
    out->visible = consume_uint8(&in);
    /* cursor */ {
        uint32_t data__nelements;
        out->cursor.flags = consume_uint32(&in);
        /* header */ {
            out->cursor.header.unique = consume_uint64(&in);
            out->cursor.header.type = consume_uint16(&in);
            out->cursor.header.width = consume_uint16(&in);
            out->cursor.header.height = consume_uint16(&in);
            out->cursor.header.hot_spot_x = consume_uint16(&in);
            out->cursor.header.hot_spot_y = consume_uint16(&in);
        }
        data__nelements = (message_end - in) / (1);
        /* use array as pointer */
        out->cursor.data = (uint8_t *)in;
        out->cursor.data_size = data__nelements;
        in += data__nelements;
    }

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_cursor_move(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgCursorMove *out;

    nw_size = 4;
    mem_size = sizeof(SpiceMsgCursorMove);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgCursorMove);
    in = start;

    out = (SpiceMsgCursorMove *)data;

    /* position */ {
        out->position.x = consume_int16(&in);
        out->position.y = consume_int16(&in);
    }

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_cursor_trail(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgCursorTrail *out;

    nw_size = 4;
    mem_size = sizeof(SpiceMsgCursorTrail);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgCursorTrail);
    in = start;

    out = (SpiceMsgCursorTrail *)data;

    out->length = consume_uint16(&in);
    out->frequency = consume_uint16(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_cursor_inval_one(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgDisplayInvalOne *out;

    nw_size = 8;
    mem_size = sizeof(SpiceMsgDisplayInvalOne);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgDisplayInvalOne);
    in = start;

    out = (SpiceMsgDisplayInvalOne *)data;

    out->id = consume_uint64(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_CursorChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
{
    static parse_msg_func_t funcs1[7] =  {
        parse_msg_migrate,
        parse_SpiceMsgData,
        parse_msg_set_ack,
        parse_msg_ping,
        parse_msg_wait_for_channels,
        parse_msg_disconnecting,
        parse_msg_notify
    };
    static parse_msg_func_t funcs2[8] =  {
        parse_msg_cursor_init,
        parse_SpiceMsgEmpty,
        parse_msg_cursor_set,
        parse_msg_cursor_move,
        parse_SpiceMsgEmpty,
        parse_msg_cursor_trail,
        parse_msg_cursor_inval_one,
        parse_SpiceMsgEmpty
    };
    if (message_type >= 1 && message_type < 8) {
        return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
    } else if (message_type >= 101 && message_type < 109) {
        return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
    }
    return NULL;
}



static uint8_t * parse_msg_playback_data(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    size_t data__nw_size;
    uint32_t data__nelements;
    SpiceMsgPlaybackPacket *out;

    { /* data */
        data__nelements = message_end - (start + 4);

        data__nw_size = data__nelements;
    }

    nw_size = 4 + data__nw_size;
    mem_size = sizeof(SpiceMsgPlaybackPacket);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgPlaybackPacket);
    in = start;

    out = (SpiceMsgPlaybackPacket *)data;

    out->time = consume_uint32(&in);
    /* use array as pointer */
    out->data = (uint8_t *)in;
    out->data_size = data__nelements;
    in += data__nelements;

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_playback_mode(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    size_t data__nw_size;
    uint32_t data__nelements;
    SpiceMsgPlaybackMode *out;

    { /* data */
        data__nelements = message_end - (start + 8);

        data__nw_size = data__nelements;
    }

    nw_size = 8 + data__nw_size;
    mem_size = sizeof(SpiceMsgPlaybackMode);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgPlaybackMode);
    in = start;

    out = (SpiceMsgPlaybackMode *)data;

    out->time = consume_uint32(&in);
    out->mode = consume_uint32(&in);
    /* use array as pointer */
    out->data = (uint8_t *)in;
    out->data_size = data__nelements;
    in += data__nelements;

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_msg_playback_start(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgPlaybackStart *out;

    nw_size = 16;
    mem_size = sizeof(SpiceMsgPlaybackStart);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgPlaybackStart);
    in = start;

    out = (SpiceMsgPlaybackStart *)data;

    out->channels = consume_uint32(&in);
    out->format = consume_uint32(&in);
    out->frequency = consume_uint32(&in);
    out->time = consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_PlaybackChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
{
    static parse_msg_func_t funcs1[7] =  {
        parse_msg_migrate,
        parse_SpiceMsgData,
        parse_msg_set_ack,
        parse_msg_ping,
        parse_msg_wait_for_channels,
        parse_msg_disconnecting,
        parse_msg_notify
    };
    static parse_msg_func_t funcs2[4] =  {
        parse_msg_playback_data,
        parse_msg_playback_mode,
        parse_msg_playback_start,
        parse_SpiceMsgEmpty
    };
    if (message_type >= 1 && message_type < 8) {
        return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
    } else if (message_type >= 101 && message_type < 105) {
        return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
    }
    return NULL;
}



static uint8_t * parse_msg_record_start(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t nw_size;
    size_t mem_size;
    uint8_t *in, *end;
    SpiceMsgRecordStart *out;

    nw_size = 12;
    mem_size = sizeof(SpiceMsgRecordStart);

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgRecordStart);
    in = start;

    out = (SpiceMsgRecordStart *)data;

    out->channels = consume_uint32(&in);
    out->format = consume_uint32(&in);
    out->frequency = consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}

static uint8_t * parse_RecordChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
{
    static parse_msg_func_t funcs1[7] =  {
        parse_msg_migrate,
        parse_SpiceMsgData,
        parse_msg_set_ack,
        parse_msg_ping,
        parse_msg_wait_for_channels,
        parse_msg_disconnecting,
        parse_msg_notify
    };
    static parse_msg_func_t funcs2[2] =  {
        parse_msg_record_start,
        parse_SpiceMsgEmpty
    };
    if (message_type >= 1 && message_type < 8) {
        return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
    } else if (message_type >= 101 && message_type < 103) {
        return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
    }
    return NULL;
}

spice_parse_channel_func_t spice_get_server_channel_parser1(uint32_t channel, unsigned int *max_message_type)
{
    static struct {spice_parse_channel_func_t func; unsigned int max_messages; } channels[7] =  {
        { NULL, 0 },
        { parse_MainChannel_msg, 111},
        { parse_DisplayChannel_msg, 313},
        { parse_InputsChannel_msg, 111},
        { parse_CursorChannel_msg, 108},
        { parse_PlaybackChannel_msg, 104},
        { parse_RecordChannel_msg, 102}
    };
    if (channel < 7) {
        if (max_message_type != NULL) {
            *max_message_type = channels[channel].max_messages;
        }
        return channels[channel].func;
    }
    return NULL;
}

uint8_t * spice_parse_msg1(uint8_t *message_start, uint8_t *message_end, uint32_t channel, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
{
    spice_parse_channel_func_t func;
    func = spice_get_server_channel_parser1(channel, NULL);
    if (func != NULL) {
        return func(message_start, message_end, message_type, minor, size_out, free_message);
    }
    return NULL;
}
